簡體   English   中英

如何修改指令中ng-repeat創建的每個元素的單獨作用域?

[英]How to modify the individual scope of each element created by ng-repeat in a directive?

我正在嘗試編寫指令以簡化Angular中的表。 我只希望用戶為指令提供list對象和html中每個列表元素的格式,例如下面的my-table標簽...

<h3>My Table</h3>
<div ng-controller='Ctrl as ctrl'>
<my-table items=ctrl.list>
    title: {{$item.title}}
    name: {{$item.name}}
</my-table>
</div> 

到目前為止,我在這里已經找到了解決問題的辦法但是我需要添加更多功能,並且遇到了問題。 在下面的my-table指令中,您可以在link函數中看到html模板。 如何在每個列表元素的單獨作用域上設置變量? 當鼠標懸停在該元素上時(使用ng-mouseenterng-mouseleave ),我應該能夠對其進行修改? 而且我應該能夠將其傳遞給模板中引用的table-edit-panel指令...

(function() {
    'use strict';

    angular
        .module('myApp')
        .directive('myTable', myTable);

    myTable.$inject = ['$compile'];

    function myTable($compile) {
        var directive = {
            transclude: true,
            scope: {    
                items: '='            
            },
            link: link  
        };
        return directive;

        function link(scope, elem, attr, ctrl, transclude) {

            scope.onMouseLeave = function(testvar) {
                testvar.state = "ready";
            };

            scope.onMouseEnter = function(testvar) {        
                testvar.state = "active";           
            };

            // not working, seems to be only one testvar rather than one for each element
            var template = 
                '<div ng-repeat="$item in items" ng-mouseenter="onMouseEnter(testvar)" ng-mouseleave="onMouseLeave(testvar)">' +
                    '<div class="row">' +                   
                    '<div class="col-md-10">' +
                        '<placeholder></placeholder>' +
                    '</div>' + 
                    '<div class="col-md-2">' +
                        '<table-edit-panel value="testvar"></table-edit-panel>' +
                    '</div>' +
                    '</div><hr/>' +
                '</div>';               

            var templateEl = angular.element(template);

            transclude(scope, function(clonedContent){
                templateEl.find("placeholder").replaceWith(clonedContent);

                $compile(templateEl)(scope, function(clonedTemplate){
                    scope.testvar = { state: "ready" }; // should be a testvar for each element of the list!
                    elem.append(clonedTemplate);
                });
            });
        }
    }
})();

您可以在jsfiddle上訪問完整的代碼。 您可以看到問題是,使用我當前的方法,當我將鼠標懸停在一個列表元素上時, testvar變量會針對所有列表元素而不是我所懸停的變量進行更改。

使用$item.testvar而不是testvar,可以訪問每個項目的子范圍。

 var template = '<div ng-repeat="$item in items" ng-init="$item.testvar.state = \'ready\'" ng-mouseenter="onMouseEnter($item.testvar)" ng-mouseleave="onMouseLeave($item.testvar)">' +
    '<div class="row">' +                   
    '<div class="col-md-10">' +
        '<placeholder></placeholder>' +
    '</div>' + 
    '<div class="col-md-2">' +
        '<table-edit-panel value="$item.testvar"></table-edit-panel>' +
    '</div>' +
    '</div><hr/>' +
'</div>';   

但是,在這種情況下,需要初始化這些狀態變量。 我添加了一個ng-init來實現這一點。 雖然這是ng-init的少數幾種預期用途之一,但在我看來,在控制器中初始化狀態變量會更清潔。

更新(這次僅使用范圍):

var template = 
    '<div ng-repeat="$item in items" ng-init="testvar.state = \'ready\'" ng-mouseenter="onMouseEnter(testvar)" ng-mouseleave="onMouseLeave(testvar)">' +
    '<div class="row">' +                   
    '<div class="col-md-10">' +
        '<placeholder></placeholder>' +
    '</div>' + 
    '<div class="col-md-2">' +
        '<table-edit-panel value="testvar"></table-edit-panel>' +
    '</div>' +
    '</div><hr/>' +
'</div>'; 

var templateEl = angular.element(template);

    transclude(scope, function(clonedContent){
        templateEl.find("placeholder").replaceWith(clonedContent);

        $compile(templateEl)(scope, function(clonedTemplate){

            // REMOVED THIS LINE:
            // scope.testvar = { state: "ready" };
            elem.append(clonedTemplate);

        });
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM