角度指令中事件参数的范围 [英] scope of event arguments in angular directive

查看:31
本文介绍了角度指令中事件参数的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the following angular app to create a menu of sections/products.

目前,当渲染并点击在每个 li 中渲染的添加"按钮时,我想添加一个部分/产品作为该部分的子部分,但是会创建多个新子项.

at present when rendered and hitting the 'add' button that is rendered within each li I want to add a section/product as a sub of that section however multiple new children are created.

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

ultimately I wish to display a form which when submitted will create the child but that is the next step. Right now I need to limit the scope to the current section and not have multiple bound clicks.

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

If you need more information please state and I will post in an edit.

一些示例数据数据.

{
    "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":[]});
    };   
});

推荐答案

我花了一点时间才弄明白,但这是基本问题,您要额外编译 section 的全部内容 2 次,并且每次编译似乎都添加了一个新的事件处理程序.

Took me a bit to figure it out but here's the basic problem, you are compiling the full contents of section 2 extra times and each compile seems to add a new event handler.

不要在每次追加新模板时编译 element 的内容,而是编译模板本身(在 DOM 之外),然后追加编译后的模板.这样 ng-click 处理程序除了初始范围创建外不会再次编译

Instead of compiling the contents of element each time you make an append of new template, compile the template itself (outside of the DOM) and then append the compiled template. This way the ng-click handler doesn't get compiled again other than initial scope creation

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

Here's an abbreviated version with one template appended:

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);        
    }

演示

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

Another approach would be to create a complete template string in link by checking for subsections and products, then compiling everything all at once....instead of using template option

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

.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

这篇关于角度指令中事件参数的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆