3

我有这两个指令,一个相互嵌套:

<envato class="container content-view-container" data-ng-cloak data-ng-hide="spinner">
    <items data-ng-repeat="items in marketplaces"></items>
</envato>

这两个中的每一个都被定义为:

Application.Envato.directive("envato", ["$timeout", function($timeout){

    var object = {

        restrict : "E",
        controller : "EnvatoAPIController",
        transclude : true,
        replace : true,
        templateUrl : "templates/envato-view.php",
        link : function(scope, element, attrs, controller) {

            console.log(scope);

            return controller.getLatestItems().then(function(data) {



                scope.marketplaces = angular.fromJson(data);
                scope.count = scope.marketplaces.length;

                var tst = angular.element(element).find(".thumbnails");

                /* $timeout(function() { scope.swiper = new Swipe(document.getElementById('swiper-container')); }, 5000); */                    
                scope.spinner = false;
            });

        }
    };

    return object;
}]);

Application.Envato.directive("items", function(){

    var iterator = [],
        object = {

            require : "^envato",
            restrict : "E",
            transclude : false,
            replace : true,
            templateUrl : "templates/envato-items-view.php",
            link : function(scope, element, attrs, controller) {

                iterator.push(element);

                if (iterator.length === scope.$parent.$parent.count) { console.log(iterator); };                                    
            }
        };

    return object;
});

上面的很多代码可能没有多大意义,因为它是更大应用程序的一部分,但我希望它对我的问题有用。我要做的是envato从指令更改指令的范围属性items。因为我有一个迭代,我想知道它什么时候完成,所以我可以在那个迭代期间对附加的 DOM 元素执行另一个操作。

例如,假设我将scope.swipe在指令中定义envato,并观察它的变化。在指令items中,我将观察何时ng-repeat完成,然后更改上面定义的范围属性scope.swipe。这将触发指令内部的变化envato,现在我知道我可以做我的操作了。

我希望我足够清楚,如果不是,我可以尝试更多代码,或者我会尝试更具体。我怎样才能实现我刚才描述的?

编辑:我知道console.log(angular.element(element.parent()).scope());在指令中使用 :items会给我指令的范围envato,但我想知道是否有更好的方法。

4

5 回答 5

4

对于这种指令间通信,我建议在envato指令上定义一个items指令可以调用的 API/方法。

var EnvatoAPIController = function($scope) {
    ...
    this.doSomething = function() { ... }
}

您的items指令已经requireenvato指令,因此在您的指令的链接函数中items,只需在适当的时候调用 API:

require : "^envato",
link : function(scope, element, attrs, EnvatoCtrl) {
   ...
   if(scope.$last) {
       EnvatoCtrl.doSomething();
   }
}

这种方法的好处在于,即使您有一天决定在指令中使用隔离作用域,它也会起作用。

AngularJS 主页上的tabs和指令使用这种通信机制。pane有关更多信息,请参阅https://stackoverflow.com/a/14168699/215945。另见约翰的指令交流视频

于 2013-03-04T18:51:26.813 回答
1

使用scope.$eval('count')atitem指令,让角度为您解析。

于 2013-03-03T15:41:32.790 回答
1

我认为您正在寻找一个在ng-repeat完成时被调用的回调。如果这就是你想要的,我已经创建了一个小提琴。http://jsfiddle.net/wjFZR/

小提琴中没有太多的用户界面。请打开萤火虫控制台,然后再次运行小提琴。您将看到一个日志。该日志在指令中ng-repeat定义的末尾调用。cell

$scope.rowDone = function(){ console.log($scope) }这是在行指令上定义的回调函数,将ng-repeat在单元指令的完成时调用。

它以这种方式注册。

<cell ng-repeat="data in rowData" repeat-done="rowDone()"></cell>

免责声明:我也是 angularjs 的新手。

于 2013-03-04T01:06:05.667 回答
1

嗯,看来您正试图让自己变得困难。在您的指令中,您没有设置范围属性:

var object = {
    restrict : "E",
    transclude : true,
    replace : true,
    scope: true,
    ...

设置范围:{} 将为您的指令提供一个完全隔离的新范围。

但是设置 scope: true 会给你的指令一个完全隔离的继承父级的新范围。

我使用此方法将模型包含在顶级父指令中,并允许它向下过滤所有子指令。

于 2013-09-18T10:38:16.203 回答
0

我喜欢 Mark 的回答,但我最终创建了一个属性指令来将元素指令的范围保存到 rootScope,如下所示:

myApp.directive('gScope', function(){
    return {
        restrict: 'A',
        replace: false,
        transclude: false,
        controller: "DirectiveCntl",
        link: function(scope, element, attrs, controller) {
            controller.saveScope(attrs.gScope);
        }
    }
});

...

function DirectiveCntl($scope, $rootScope) {
    this.saveScope = function(id) {
        if($rootScope.directiveScope == undefined) {
            $rootScope.directiveScope = [];
        }
        $rootScope.directiveScope[id] = $scope;
    };
}

...

<span>Now I can access the message here: {{directiveScope['myScopeId'].message}}</span>
<other-directive>
    <other-directive g-scope="myScopeId" ng-model="message"></other-directive>
</other-directive>

注意:虽然这使得从所有各种指令中收集数据变得很容易,但我提醒您,现在您必须确保正确管理潜在的范围堆,以避免导致页面上的内存泄漏。特别是如果您使用 ng-view 创建单页应用程序。

于 2013-08-29T20:36:50.573 回答