【问题标题】:AngularJS : directives and scopeAngularJS:指令和范围
【发布时间】:2013-10-02 16:52:10
【问题描述】:

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

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

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

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

console.dir(scope)

我可以在范围对象中看到我所追求的属性('pages')。

如果我尝试这样做:

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;
        });
    }
});

【问题讨论】:

  • 你能显示你使用指令的模板的代码吗?以及您设置 scope.pages 值的控制器?
  • 确定 scope.pages 是undefined 而不是空对象或数组吗?当您扩大范围以在控制台中查看 pages 属性时,它说明了什么?我看不出它应该说出与输出 scope.pages 不同的任何理由,所以我的回答会假设您实际上看到的是一个空对象或数组。

标签: javascript angularjs-directive


【解决方案1】:

您的代码中的问题是:MachineServices.getByCustomerIdMachineServices.query异步。当你调用这些函数时,来自服务器的数据还没有到达,这些行

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

尚未调用

链接函数中的作用域绑定到父作用域。但是当link函数被调用时,父级的scope.pages 仍然是未定义的(由于异步)

当我们使用角度数据绑定时,我们应该被动,只听变化并做出相应的反应(例如使用 $watch),因为我们的代码不知道也不应该知道绑定的属性何时有值或更新了它的值。 Let angular notify us the changes

【讨论】:

  • 我在学习之前有时会遇到这个问题。我的解决方法是使用ng-if
  • @gustavohenke:我认为我们不应该那样做,当我们使用数据绑定时,我们应该尽可能passive
【解决方案2】:

看起来您正在为您的 MachineServices 使用 angular $resource,对吧?这将为您的结果创建一个空对象或数组,您可以立即绑定到该对象或数组,然后在调用异步完成时填充结果。当 link 被 Angular 调用时,它还不会填充数据。

首先将日志记录添加到您的 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);
            });
        }
    }
});

【讨论】:

    【解决方案3】:

    尝试将作用域注入您的指令。

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

    【讨论】:

      【解决方案4】:

      这是使用 Ng 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']);
              }
          }
      });
      

      请注意,我将 $scope 注入控制器。

      【讨论】:

        猜你喜欢
        • 2014-11-24
        • 2014-10-02
        • 1970-01-01
        • 1970-01-01
        • 2017-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多