简体   繁体   English

在ng-repeat内部呈现的指令中更新Controller $ scope属性

[英]Updating Controller $scope property in directive rendered inside ng-repeat

I have created a fiddle (it was my first, so was quite a headache to get going!): http://jsfiddle.net/rmN59/17/ . 我创建了一个小提琴(这是我的第一个,所以上手相当头疼!): http : //jsfiddle.net/rmN59/17/

<div ng-controller="MainCtrl">

<div ng-repeat='d in data'>
    <div id="container-{{ d.key }}">
        <h3>My text {{ d.key }}</h3>
    </div>

    <div class='myDirective' overlay-contents='$parent.overlayContents' name='container-{{ d.key }}'></div>
</div>
<div id="overlay" class="hidden" ng-click="hideOverlay($event)">
    <div ng-bind-html='overlayContents'></div>
</div>

    var myApp = angular.module('myApp',[]);

myApp.controller('MainCtrl', ['$scope', function ($scope) {
    var overlaySelector = '#overlay';
    var showOverlay = function(){
        $(overlaySelector).toggleClass('hidden');
    };

    $scope.data = [{ key: '1' }, { key: '2' }];

    $scope.overlayContents = 'alex';

    $scope.$watch('overlayContents', function(newVal, oldVal){
        if(newVal !== oldVal){
            showOverlay();
        }
    });

    $scope.hideOverlay = function(e){
        var target = $(e.target);

        if(target.is(overlaySelector)){
            target.toggleClass('hidden');
        };

        e.stopPropagation();
    };
}]);


myApp.directive('myDirective', ['$sce', function($sce){
    return {
        scope: {
            overlayContents: '=',
            container: '@name'
        },
        template: '<button>Click</button>',
        restrict: 'C',
        link: function(scope, element){
            var stripAngularProps = function(html){
                return html.replace(/ng-(scope|binding|bind-html="[\w\(\)\.\[\]]+")/g,'');
            };

            element.click(function(e){
                var container = $('#' + scope.container);

                if($(e.target).is(element.find('button'))){
                    var html = stripAngularProps(container.html());

                    scope.$apply(function(){
                        scope.overlayContents = $sce.trustAsHtml(html);
                    });
                }
            });
        }
    }
}]);

I have data I need to iterate over and create a directive for each iteration. 我有需要迭代的数据并为每次迭代创建一个指令。 I then have an overlay directive outside of the loop that will listen for changes to a model on the controller (overlayContents). 然后,我在循环外部有一个overlay指令,该指令将监听控制器上模型的更改(overlayContents)。 At which point, the controller will display the overlay with the updated contents. 此时,控制器将显示带有更新内容的叠加层。

The $scope.$watch in the controller never fires. 控制器中的$ scope。$ watch从不触发。

UPDATE: It works in the fiddle! 更新:它在小提琴中起作用! Annoyingly. 烦人。 The only difference I can see is that here I'm using dummy data and in my real project I'm using separate files for the templates. 我可以看到的唯一区别是,这里我使用的是虚拟数据,而在我的真实项目中,我使用的模板是单独的文件。 I've been pulling what hair I have left out for hours! 我已经拉了几个小时不留头发了!

UPDATE 2: The overlayContents property DOES get updated, and it is reflected in the DOM, but the $watch is not called. 更新2:overlayContents属性确实得到更新,并反映在DOM中,但未调用$ watch。

I have fixed it myself. 我自己修好了。 Sorry for not being able to put more specific code. 抱歉,无法放置更多特定的代码。

By removing the DOM manipulation in the controller and moving it into an overlay directive which watches for changes to the overlayContents this seems to work. 通过删除控制器中的DOM操作并将其移动到一个overlay指令中,该指令监视对overlayContents的更改,这似乎起作用。 Perhaps because the $watch is added in the link function which is after the compile stage. 可能是因为在编译阶段之后,在链接函数中添加了$ watch。 I'm still getting my head round how Angular works. 我仍然对Angular的工作方式有所了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM