AngularJS - 如何在链接函数中获取隔离的指令范围变量?

时间:2016-01-13 07:45:18

标签: javascript angularjs angularjs-directive angularjs-scope

请参阅下面的代码。

指令:

app.directive("filterTree", function() {
    return {
        restrict: "AE",
        controller: function($scope, $http){
            $scope.treeNodes = [];
            var filterItemsUrl = "/api/v1/users/userId/filter_nodes";
            $http.get(filterItemsUrl).success(function(response) {
                var filterItems = response["data"]["filter_nodes"];
                filterItems.map(function(item){
                    $scope.treeNodes.push({
                        id: item.id,
                        pId: item.pid,
                        name: item.name,
                        open: item.open,
                        checked: item.checked
                    });
                });
            });
        },
        link: function(scope, element, attributes, controller){
            var setting = {
                check: {
                    enable: true
                },
                data: {
                    simpleData: {
                        enable: true
                    }
                }
            };

            $.fn.zTree.init(element, setting, scope.treeNodes);
        }
    };
});

HTML:

<ul class="ztree" filter-tree="" id="filterTree"></ul>
我的链接功能无法访问

scope.treeNodes。如何在链接函数中访问此隔离区范围变量?

3 个答案:

答案 0 :(得分:1)

  

有没有办法告诉链接功能等到控制器功能完全执行?

您需要使用httpPromise来执行$.fn.zTree.init

app.directive("filterTree", function() {
    return {
        restrict: "AE",
        controller: function($scope, $http, $element){
            $scope.treeNodes = [];
            var filterItemsUrl = "/api/v1/users/userId/filter_nodes";
            //save httpPromise
            var httpPromise = $http.get(filterItemsUrl);
            //chain from httpPromise
            httpPromise.then(function(response) {
                var filterItems = response.data["data"]["filter_nodes"];
                filterItems.map(function(item){
                    $scope.treeNodes.push({
                        id: item.id,
                        pId: item.pid,
                        name: item.name,
                        open: item.open,
                        checked: item.checked
                    });
                });
                //return treeNodes for chaining zTree.init
                return $scope.treeNodes;
            }).then (function onFulfilled (treeNodes) {
                var setting = {
                    check: { enable: true },
                    data: { simpleData: { enable: true }
                };
                //execute zTree.init
                $.fn.zTree.init($element, setting, treeNodes);
            })
        },
        link: function(scope, element, attributes, controller){
        }
    };
});

$q服务在执行onFulfilled方法的.then函数之前等待履行承诺。通过这种方式,zTree.init的执行得到了适当的延迟。

有关链接承诺的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises

还要注意在控制器函数中注入本地$element

有关控制器本地的更多信息,请参阅AngularJS $compile Service API Reference -- controller

.success服务的.error$http方法已被弃用。有关详细信息,请参阅AngularJS $http Service API Reference -- deprecation notice

答案 1 :(得分:0)

首先,您创建的指令不具有隔离范围但具有继承范围,即它与父控制器共享范围。

对于隔离范围,您必须将指令的范围定义为这样的对象:

scope: {
    //your binded attributes here
} 

要访问$scope.treeNodes,请将其作为属性传递:

<ul class="ztree" filter-tree tree-nodes="treeNodes" id="filterTree"></ul>

并将其绑定在您的指令中:

restrict: 'AE',
scope: {
    tree_nodes: '=treeNodes' //'=' for two way binding
}

scope.tree_nodes现已绑定到控制器$scope.treeNodes的两端。

答案 2 :(得分:0)

可以在链接函数中访问scope.treeNodes,请查看以下plunk([Hyperlink here] [1])。

这里的问题是你在控制器中做一个异步请求的HTTP请求,到加载数据时,链接功能已经被执行,这就是没有加载数据的原因。

您需要以这样的方式重写它,以便在执行链接功能时,数据在此之前由http请求加载。