如何选择从AngularJS指令内部动态生成的元素呢? [英] How to select dynamically generated elements from inside an AngularJS directive?

查看:146
本文介绍了如何选择从AngularJS指令内部动态生成的元素呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的指导,我需要选择出一定的DOM元素,其中一些是在NG-重复循环动态生成的。如果我在一个简单的方法做,我只会静态元素。不过,如果我耽搁,比方说,500毫秒的选择,我将所有的元素,这就是我想要的。

虽然这个工作,它不是一个理想的解决方案,当然似乎不是最好的做法。在一方面,你想保持超时越短越好,但另一方面,你要肯定的是,DOM是选择前准备好。

有没有当所有动态DOM就绪这触发一个事件?什么是选择从AngularJS指令动态生成的元素推荐的方式?

示例:

HTML

 < D​​IV数据我-指令>
    < D​​IV CLASS =模体>
        <标签数据本地化>类型:LT; /标签>&安培; NBSP;
        <选择类=表格控NG模型=assetFilter.app codeNG-变化=loadassets(assetFilter.app code)NG选项=类型code作为type.name在类型类型>< /选择>            <表类=表的表默认NG秀=hasLoaded>
                < TBODY NG重复=资产的资产|过滤器:assetFilter |排序依据:'assetKey:假>
                &所述; TR>
                    &所述; TD>
                        < D​​IV CLASS =集装箱液>
                            < D​​IV CLASS =行VERT对齐>
                                < D​​IV CLASS =COL-SM-4>
                                    {{asset.assetKey}}
                                < / DIV>
                                < D​​IV CLASS =COL-SM-8的风格=高度:100%>
                                    <输入NG隐藏=asset.assetKey.length> = 80类型=文本级=表格控NG模型=asset.assetValueNG变化=asset.isModified =真 >
                                    < textarea的NG-秀=asset.assetKey.length> 80级=表格控NG模型=asset.assetValueNG变化=asset.isModified =真正的>< / textarea的&GT ;
                                < / DIV>
                            < / DIV>
                        < / DIV>
                    < / TD>
                < / TR>
            < / TBODY>
        < /表>    < / DIV>
    < D​​IV CLASS =模式躯>
        <按钮类=BTN BTN-主要NG点击=保存(saveassets,$事件)NG-禁用=(资产| anyModified)!数据本地化>保存< /按钮>
        <按钮类=BTN BTN-警告NG点击=关闭($事件)数据本地化>关闭< /按钮>
    < / DIV>
< / DIV>

指令:

  myApp.directive('myDirective',函数($超时){
    返回{
        只有'A',//属性:限制
        链接:功能(范围,ELEM,ATTR,CTRL){
            VAR背景= ELEM [0];
            VAR availableFormElements ='输入:不使用(禁用):不使用(类* = NG隐藏]),'+
                选择:不使用(禁用):不使用(类* = NG隐藏]),文本区域:不使用(禁用):不使用(类* = NG隐藏]),'+
                按钮:不使用(禁用):不使用(类* = NG隐藏]),'+
                * [*类= BTN]:不使用(禁用):不使用(类* = NG隐藏])';            VAR allFormElements = context.querySelectorAll(availableFormElements);
            //只会静态元素,从没有NG-repeat循环            $超时(函数(){
                allFormElements = context.querySelectorAll(availableFormElements);
                //将包括所有的元素,也NG-repeat循环
            },500);            // code操纵选定表单元素    };
});


解决方案

这是一个简单的例子,你如何可以工作了。
伊莫该解决方案唯一的缺点是你不能使用分离的范围。

HTML

 < D​​IV数据-NG-控制器=MainController>
    < D​​IV外指令>
        < UL>
            <李NG重复=资产资产内指令>
                      {{资产}}
                      <输入类型=文本级=表格控>
            < /李>
        < / UL>
    < / DIV>
< / DIV>

JS

  VAR应用= angular.module('对myApp',[]);app.controller('MainController',函数($范围){
    $ scope.assets = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
});app.directive('outerDirective',函数(){
  返回{
    限制:'A',
    控制器:函数($范围){    }
  };
});
app.directive('innerDirective',函数(){
  返回{
    限制:'A',
    要求:'^ outerDirective',
    链接:功能(范围,ELEM,ATTRS,CTRL){
        VAR背景= ELEM [0];
        如果(范围。$最后一个){
            VAR availableFormElements ='输入,文本区域;
            VAR allFormElements = context.querySelectorAll(availableFormElements);
            的console.log(allFormElements);
        }
    }
  };
});

或更好

  .directive('myParent',函数($超时){
        返回{
            只有'A',//属性:限制
            控制器:函数($范围,$元素){
                this.isDone =功能(){
                    变种上下文= $元件[0];
                    VAR availableFormElements ='输入,文本区域;
                    VAR allFormElements = context.querySelectorAll(availableFormElements);
                    的console.log(allFormElements);
                }
            }
        };
    })
    .directive('myChild',函数($超时){
        返回{
            要求:'^ myParent',
            只有'A',//属性:限制
            链接:功能(范围,ELEM,ATTR,CTRL){                如果(范围。$最后一个){
                    ctrl.isDone();
                }
            }
        };
    })

BTW
请勿触摸DOM控制器:)

In my directive, I need to select out certain DOM elements, some of which are generated dynamically in an ng-repeat loop. If I do it in a straightforward way, I will only get the static elements. However, if I delay the selection by, say, 500ms, I will get all elements, which is what I want.

Although this works, it is not an ideal solution, and certainly doesn't seem like best practise. On the one hand, you'd like to keep the timeout as short as possible, but on the other hand, you want to be sure that the DOM is ready before selecting.

Is there an event which fires when all dynamic DOM is ready? What is the recommended way to select dynamically generated elements from an AngularJS directive?

EXAMPLE:

HTML:

<div data-my-directive>
    <div class="modal-body">                        
        <label data-localize>type:</label>&nbsp;
        <select class="form-control" ng-model="assetFilter.appCode" ng-change="loadassets(assetFilter.appCode)" ng-options="type.code as type.name for type in types"></select>

            <table class="table table-default" ng-show="hasLoaded">
                <tbody ng-repeat="asset in assets | filter:assetFilter | orderBy:'assetKey':false">
                <tr>
                    <td>
                        <div class="container-fluid">
                            <div class="row vert-align">
                                <div class="col-sm-4">
                                    {{asset.assetKey}}
                                </div>
                                <div class="col-sm-8" style="height:100%">
                                    <input ng-hide="asset.assetKey.length >= 80" type="text" class="form-control" ng-model="asset.assetValue" ng-change="asset.isModified=true">
                                    <textarea ng-show="asset.assetKey.length > 80" class="form-control" ng-model="asset.assetValue" ng-change="asset.isModified=true"></textarea>
                                </div>
                            </div>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>

    </div>
    <div class="modal-footer">
        <button class="btn btn-primary" ng-click="save(saveassets, $event)" ng-disabled="!(assets | anyModified)" data-localize>Save</button>
        <button class="btn btn-warning" ng-click="close($event)" data-localize>Close</button>
    </div>
</div>

Directive:

myApp.directive('myDirective', function ($timeout) {
    return {
        restrict: 'A', //attribute only
        link: function (scope, elem, attr, ctrl) {    
            var context = elem[0]; 
            var availableFormElements = 'input:not([disabled]):not([class*=ng-hide]),' +
                'select:not([disabled]):not([class*=ng-hide]), textarea:not([disabled]):not([class*=ng-hide]),' +
                'button:not([disabled]):not([class*=ng-hide]),' +
                '*[class*=btn]:not([disabled]):not([class*=ng-hide])';

            var allFormElements = context.querySelectorAll(availableFormElements);
            // Will only get static elements, nothing from ng-repeat loop

            $timeout(function () {
                allFormElements = context.querySelectorAll(availableFormElements);
                // Will include all elements, also from ng-repeat loop
            }, 500);     

            // Code to manipulate selected form elements   

    };
});

解决方案

This is a simple example how you could work it out. Imo the only drawback to this solution is you can't use an isolate scope.

html

<div data-ng-controller="MainController">
    <div outer-directive>
        <ul>
            <li ng-repeat="asset in assets" inner-directive>
                      {{asset}}
                      <input type="text" class="form-control">
            </li>
        </ul>
    </div>
</div>

js

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

app.controller('MainController',function($scope) {
    $scope.assets = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 
});

app.directive('outerDirective', function() {
  return {
    restrict: 'A',
    controller: function($scope) {

    }
  };
});
app.directive('innerDirective', function() {
  return {
    restrict: 'A',
    require: '^outerDirective',
    link: function(scope, elem, attrs,ctrl) {
        var context = elem[0]; 
        if (scope.$last){
            var availableFormElements = 'input,textarea';
            var allFormElements = context.querySelectorAll(availableFormElements);
            console.log(allFormElements);
        }
    }
  };
});

or better

.directive('myParent', function ($timeout) {
        return {
            restrict: 'A', //attribute only
            controller: function ($scope, $element) { 
                this.isDone = function(){
                    var context = $element[0]; 
                    var availableFormElements = 'input,textarea';
                    var allFormElements = context.querySelectorAll(availableFormElements);
                    console.log(allFormElements);
                }
            }
        };
    })
    .directive('myChild', function ($timeout) {
        return {
            require:'^myParent',
            restrict: 'A', //attribute only
            link: function (scope, elem, attr, ctrl) {    

                if (scope.$last){
                    ctrl.isDone();
                }
            }
        };
    })

BTW Don't touch the dom in the controller :)

这篇关于如何选择从AngularJS指令内部动态生成的元素呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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