AngularJS:指令和范围

时间:2013-10-02 16:52:11

标签: javascript angularjs-directive

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

我正在为我的应用设置一个简单的指令。我将scope属性设置为默认值“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;
        });
    }
});

4 个答案:

答案 0 :(得分:4)

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

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

尚未调用

您的链接函数中的范围绑定到父级的范围。但是当调用link函数时,父级的scope.pages 仍未定义(由于asyn)

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

答案 1 :(得分:1)

看起来你正在为你的MachineServices使用angular $ resource,对吧?这会为您的结果创建一个空对象或数组,您可以立即绑定它,以便在调用异步完成时稍后填充结果。当通过角度调用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);
            });
        }
    }
});

答案 2 :(得分:0)

尝试将范围注入您的指令。

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

答案 3 :(得分:0)

以下是使用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注入控制器。