2013-10-02 188 views
3

我有一个简单的问题,我认为有一个非常简单的解决方案,但不知何故,我错过了它。AngularJS:指令和范围

我为我的应用程序设置了一个简单的指令。我将scope属性设置为默认值“false”,因为我希望它共享我的控制器的范围。

问题是,我似乎无法访问该范围。

在我的链接功能,我可以这样做:

console.dir(scope) 

,我可以看到我之后的范围对象(“页”)的财产。

如果我尝试这样做:

console.dir(scope.pages) 

然而,它回来为未定义。

我错过了什么?

在此先感谢。

MyDirectives.directive("mdPagination", function(){ 
    return { 
     templateURL: "/templates/pagination.html", 
     replace: true, 
     restrict: 'A', 
     scope: false, //default 
     link: function(scope, element, attrs){ 
      console.log('in linking function'); 
      console.dir(scope); 
      console.dir(element); 
      console.dir(attrs); 
      console.dir(scope.pages); 
     } 
    } 
}); 

模板:

<nav class="pagination" md-Pagination></nav> 

控制器:

App.controller('MachinesListCtrl', function ($scope, $routeParams, $location, MachineServices, CustomerServices) { 

    var page = ($routeParams.page ? $routeParams.page : 1); 

    //if we are getting all machines based on their customer id. 
    if($routeParams.customerID){ 
     MachineServices.getByCustomerId($routeParams.customerID).then(function (data) { 
      _.each(data.results, function (machine, index, list) { 
       CustomerServices.get(machine.customer_id).then(function(data){ 
        machine.CustomerData = data.results; 
       }); 
      }); 

      $scope.Machines = data.results; 
      $scope.pages = data.pages; 
     }); 
    } 
    //otherwise we just want the regular list of machines. 
    else{ 
     MachineServices.query(page).then(function (data) { 
      _.each(data.results, function (machine, index, list) { 
       CustomerServices.get(machine.customer_id).then(function(data){ 
        machine.CustomerData = data.results; 
       }); 
      }); 

      $scope.Machines = data.results; 
      $scope.pages = data.pages; 
     }); 
    } 
}); 
+1

能否请你告诉模板的代码中使用的指令?和控制器在哪里设置scope.pages的值? –

+0

你确定* scope.pages是未定义的,而不是空对象或数组?当您扩展范围以查看控制台中的页面属性时,它说了什么?我看不出有什么理由说它应该说出与输出'scope.pages'不同的东西,所以我的答案会假设你实际上看到了一个空的对象或数组。 –

回答

4

在你的代码的问题是:MachineServices.getByCustomerIdMachineServices.query异步。当你调用这些功能,从服务器的数据还没有到达,这些线路

$scope.Machines = data.results; 
    $scope.pages = data.pages; 

不叫尚

链接函数的作用域被绑定到父类的作用域。但是,当link函数被调用时,父母的scope.pages 仍然不确定的(由于ASYN)

当我们一起工作的角度数据绑定,我们应该被动,只是听(例如使用$ watch),因为我们的代码不知道,也不应该知道当绑定属性有值或更新其值时。Let angular notify us the changes

+0

我在学习之前有时会遇到这个问题。我的修复是使用'ng-if'。 – gustavohenke

+0

@gustavohenke:我认为我们不应该这样做,当我们使用数据绑定的时候,我们应该尽可能地做到“被动”。 –

0

尝试注射范围到你的指令。

MyDirectives.directive("mdPagination", function($scope){... 
0

这里是伍1.2工作代码:

http://jsfiddle.net/roadprophet/PfEaz/

MyDirectives.directive("mdPagination", function(){ 
    console.log('BLAH'); 
    return { 
     template: "<h1>BLAH!</h1>", 
     replace: true, 
     restrict: 'A', 
     scope: false, //default 
     link: function(scope, element, attrs){ 
      console.log('in linking function'); 
      console.dir(scope); 
      console.dir(element); 
      console.dir(attrs); 
      console.dir(scope['pages']); 
     } 
    } 
}); 

通知我注入$范围到控制器。

1

看起来你正在为MachineServices使用角度$资源,对吧?这会为您的结果创建一个空对象或数组,以便您可以立即将其绑定到该对象或数组,以便稍后在调用异步完成时填充结果。当按角度调用link时,它将不会填充数据。

首先将日志记录添加到您的querygetByCustomerId调用中,以确保它们获取值并正确设置示波器上的属性。将{{pages|json}}添加到您的模板中的某个位置,以便在页面发生更改时查看JSON。如果你看到那么你可以看这个属性在你的指令,如果你需要做一些特别的东西,当它改变:

MyDirectives.directive("mdPagination", function(){ 
    return { 
     templateURL: "/templates/pagination.html", 
     replace: true, 
     restrict: 'A', 
     scope: false, //default 
     link: function(scope, element, attrs){ 
      console.log('in linking function'); 
      console.dir(scope); 
      console.dir(element); 
      console.dir(attrs); 
      console.dir(scope.pages); 

      // watch pages for changes 
      scope.$watch('pages', function(value) { 
       console.log("pages now has this value:"); 
       console.dir(scope.pages); 
      }); 
     } 
    } 
});