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

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

问题描述

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

在present渲染,打了每次里我想添加一个节/产品作为部分创建多个但是新的儿童的子内呈现的添加按钮时。

最后我想显示的提交将创建儿童在一个形式,但是这是下一步。现在我需要的范围限制于当前节,而不是具有多个结合点击。

如果您需要了解更多信息,请注明,我将张贴在编辑。

有些样本数据。

  {
    节:[
        {
            名:标志,
            节:[
                {
                    名:欧洲,
                    节:[],
                    产品:[
                        {名:法国},
                        {名:德国},
                        {名:爱尔兰},
                        {名:英格兰队}
                    ]
                },
                {
                    名:非洲,
                    节:[],
                    产品:[
                        {名:埃及},
                        {名:尼日利亚},
                        {名:乍得}                    ]
                },
                {
                    名:南美
                    节:[],
                    产品:[
                        {名:巴西},
                        {名:阿根廷队},
                        {名:秘鲁}
                    ]
                }
            ]
            产品:[]
        },
        {
            名:地图
            节:[
                {
                    名:非洲,
                    节:[],
                    产品:[
                        {名:埃及},
                        {名:尼日利亚},
                        {名:乍得}                    ]
                },
                {
                    名:南美
                    节:[],
                    产品:[
                        {名:巴西},
                        {名:阿根廷队},
                        {名:秘鲁}
                    ]
                }            ]
            产品:[]
        }
    ]
    产品:[]
}

该应用程序。

 使用严格的;VAR menuApp = angular.module('menuApp',[]);menuApp
    .directive('节',函数(){
        返回{
            限制:E,
            更换:真实,
            范围: {
                部分:'='
            },
            模板:'&所述; UL><节纳克重复=部分中的部分部分=部分/>&下; / UL>'
        };
    })
    .directive('节',函数($编译){
        返回{
            限制:E,
            更换:真实,
            范围: {
                部分:=一节
            },
            模板:'<李班=部分> {{section.name}}<按钮NG点击=addSub(部分)>添加< /按钮>< /李>,
            链接:函数(范围,元素,ATTRS,控制器){
                如果(angular.isArray(scope.section.sections)){
                    element.append(<部分路段='section.sections'>< /段>中);
                    $编译(element.contents())(范围);
                }
                如果(angular.isArray(scope.section.products)){
                    element.append(<产品产品='section.products'>< /产品>);
                    $编译(element.contents())(范围);
                };
            },
            控制器:函数($范围){
                的console.log($范围内);
                $ scope.addSub =功能(部分){
                    //console.log(section,'Adding子');
                    section.sections.push({名:节,节:[],产品:[]});
                };
            }
        };
    })
    .directive('产品',函数(){
        返回{
            限制:E,
            更换:真实,
            范围: {
                产品:'='
            },
            模板:'< UL><产品NG重复=产品在产品的产品=产品>< /产品>< / UL>'
        };
    })
    .directive(产品,功能($编译){
        返回{
            限制:E,
            更换:真实,
            范围: {
                产品:'='
            },
            模板:'<李班=产品> {{product.name}}< /李>'
        };
    });menuApp.controller('menuCtrl',功能menuCtrl($范围,$ HTTP){
    $ http.get('/ AJAX / getvenuesmenu?venueID ='+ venueMenu.venueId).success(功能(RESP){
        $ scope.sections = RESP;
    });    $ scope.add =功能(数据){
        data.push({名:节,节:[]});
    };
});


解决方案

我花了一点的数字出来,但这里是基本的问题,你正在编译部分的全部内容 2个额外的时间和每次编译似乎添加一个新的事件处理程序。

而不是编译元素的每次做出新模板追加时间的内容,编译模板本身(外的DOM),然后追加编译模板。这样, NG-点击处理程序不会被再次编译比初步范围创建其他

下面是一个缩略版与一个模板附加:

 链接:功能(范围,元素,ATTRS,控制器){
    如果(angular.isArray(scope.section.sections)){
        / *编译DOM之外* /
        VAR小节= $编译(<部分路段='section.sections'>< /段>中)(范围);
        / *追加编译* /
        element.append(小节);
    }

<大骨节病> 演示

另一种方法是通过检查小节和产品,然后编译所有的一切一下子....而不是使用<$创造链接一个完整的模板字符串C $ C>模板选项

code的另一种方法在一次编译完成部分:

  .directive('节',函数($编译,$超时){
    返回{
        限制:E,
        范围: {
            部分:=一节
        },
        链接:函数(范围,元素,ATTRS,控制器){
            VAR模板='&LT;李班=部分&GT; {{section.name}}&LT;按钮NG点击=addSub(部分)&gt;添加&LT; /按钮&GT;';            如果(angular.isArray(scope.section.sections)){
                模板+ =&LT;部分路段='section.sections'&GT;&LT; /段&gt;中;
            }
            如果(angular.isArray(scope.section.products)){
                模板+ =&LT;产品产品='section.products'&GT;&LT; /产品&gt;中;
            };            模板+ ='&LT; /李&GT;';            VAR compiledTemplate = $编译(模板)(范围);
            element.replaceWith(compiledTemplate);            scope.addSub =功能(部分){
                section.sections.push({名:节,节:[],产品:[]
                });
            };
        }
    };
})

<大骨节病> DEMO-Alt键

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

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.

Some sample data data.

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

The app.

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

解决方案

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.

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

DEMO

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

Code for alternate approach compiling complete section at once:

.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天全站免登陆