angular指令中的事件参数范围

时间:2013-12-09 02:17:47

标签: angularjs angularjs-directive angularjs-scope

我有以下角度应用程序来创建部分/产品的菜单。

目前在渲染并点击每个li中呈现的“添加”按钮时,我想添加一个部分/产品作为该部分的子部分,但是创建了多个新子项。

最终我希望显示一个表单,该表单在提交时将创建子项,但这是下一步。现在我需要将范围限制在当前部分,而不是有多个绑定点击。

如果您需要更多信息,请说明,我将在编辑中发布。

一些示例数据数据。

{
    "sections":[
        {
            "name":"Flags",
            "sections":[
                {
                    "name":"Europe",
                    "sections":[],
                    "products":[
                        { "name": "France" },
                        { "name": "Germany" },
                        { "name": "Ireland" },
                        { "name": "England" }
                    ]
                },
                {
                    "name": "Africa",
                    "sections":[],
                    "products":[
                        { "name": "Egypt" },
                        { "name": "Nigeria" },
                        { "name": "Chad" }

                    ]
                },
                {
                    "name": "South America",
                    "sections":[],
                    "products": [
                        { "name": "Brasil" },
                        { "name": "Argentina" },
                        { "name": "Peru" }
                    ]
                }
            ],
            "products":[]
        },
        {
            "name": "Maps",
            "sections":[
                {
                    "name": "Africa",
                    "sections":[],
                    "products":[
                        { "name": "Egypt" },
                        { "name": "Nigeria" },
                        { "name": "Chad" }

                    ]
                },
                {
                    "name": "South America",
                    "sections":[],
                    "products": [
                        { "name": "Brasil" },
                        { "name": "Argentina" },
                        { "name": "Peru" }
                    ]
                }

            ],
            "products":[]
        }        
    ],
    "products":[]
}

该应用。

'use strict';

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

menuApp
    .directive('sections', function () {
        return {
            restrict: "E",
            replace: true,
            scope: {
                sections: '='
            },
            template: '<ul><section ng-repeat="section in sections" section="section" /></ul>'
        };
    })
    .directive('section', function ($compile) {
        return {
            restrict: "E",
            replace: true,
            scope: {
                section: '=section'
            },
            template: '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button></li>',
            link: function (scope, element, attrs, controller) {
                if (angular.isArray(scope.section.sections)) {
                    element.append("<sections sections='section.sections'></sections>"); 
                    $compile(element.contents())(scope);
                }
                if(angular.isArray(scope.section.products)){
                    element.append("<products products='section.products'></products>"); 
                    $compile(element.contents())(scope);
                };
            },
            controller : function($scope){
                console.log($scope);
                $scope.addSub = function (section){
                    //console.log(section,'Adding Sub');
                    section.sections.push({"name":"Section","sections":[],"products":[]});
                };
            }
        };
    })
    .directive('products', function () {
        return {
            restrict: "E",
            replace: true,
            scope: {
                products: '='
            },
            template: '<ul><product ng-repeat="product in products" product="product"></product></ul>'
        };
    })
    .directive('product', function ($compile) {
        return {
            restrict: "E",
            replace: true,
            scope: {
                product: '='
            },
            template: '<li class="product">{{product.name}}</li>'
        };
    });

menuApp.controller('menuCtrl', function menuCtrl($scope,$http) {
    $http.get('/ajax/getvenuesmenu?venueID='+venueMenu.venueId).success(function(resp) {
        $scope.sections = resp;
    });

    $scope.add = function(data){
        data.push({"name":"Section","sections":[]});
    };   
});

1 个答案:

答案 0 :(得分:1)

我想了解一下,但这是基本问题,你正在编译section 2的全部内容,每次编译似乎都会添加一个新的事件处理程序。

每次添加新模板时,不要编译元素的内容,而是编译模板本身(在DOM之外),然后附加编译后的模板。这样,除了初始范围创建

之外,ng-click处理程序不会再次编译

这是一个附加了一个模板的缩写版本:

link: function (scope, element, attrs, controller) {
    if (angular.isArray(scope.section.sections)) {
        /* compile outside of the DOM*/
        var subsections = $compile("<sections sections='section.sections'></sections>")(scope);
        /* append compilation*/
        element.append(subsections);        
    }

DEMO

另一种方法是在link中创建一个完整的模板字符串,方法是检查子部分和产品,然后一次编译所有内容......而不是使用template选项

备用方法的代码一次编译完整部分:

.directive('section', function ($compile, $timeout) {
    return {
        restrict: "E",
        scope: {
            section: '=section'
        },
        link: function (scope, element, attrs, controller) {
            var template = '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button>';

            if (angular.isArray(scope.section.sections)) {
                template += "<sections sections='section.sections'></sections>";
            }
            if (angular.isArray(scope.section.products)) {
                template += "<products products='section.products'></products>";
            };

            template += '</li>';

            var compiledTemplate = $compile(template)(scope);
            element.replaceWith(compiledTemplate);

            scope.addSub = function (section) {
                section.sections.push({ "name": "Section", "sections": [], "products": []
                });
            };       
        }
    };
})

DEMO-Alt