Javascript 使用ng repeat动态加载指令

Javascript 使用ng repeat动态加载指令,javascript,html,angularjs,Javascript,Html,Angularjs,我用自己的指令包装HTML“select”元素。该指令应创建一个代表其选项的下拉菜单 我用自定义的“arBootstrapSelect”指令/属性标记select元素。 该指令附加了一个下拉菜单,其中的选项由ng repeat重复 “select”元素中的“option”元素标记为“arBootstrapSelectOption”。它们应该有一个“content”属性,表示一个动态指令。应编译此动态指令并在下拉菜单中显示 基本上,每个选项(标记为“arbotstrapselectoption”)

我用自己的指令包装HTML“select”元素。该指令应创建一个代表其选项的下拉菜单

我用自定义的“arBootstrapSelect”指令/属性标记select元素。 该指令附加了一个下拉菜单,其中的选项由ng repeat重复

“select”元素中的“option”元素标记为“arBootstrapSelectOption”。它们应该有一个“content”属性,表示一个动态指令。应编译此动态指令并在下拉菜单中显示

基本上,每个选项(标记为“arbotstrapselectoption”)都使用$compile服务编译其“content”属性,并将其注入arbotstrapselect指令中的列表中。之后,arBootstrapSelect应使用ng repeat显示已编译的选项。希望不要太复杂。 我越来越

HTML:

这是可行的,但它又丑又慢:

(function () {
'use strict';
var app = angular.module('mainApp');

app.directive('arBootstrapSelect', function ($interval, $compile) {
    //$scope.arBootstrapSelectOptions = [];

    function link(scope, element, attrs) {
        //element.hide();

        scope.$on('arBootstrapSelectNewItem', function (event, data) {
            var test = $('<li></li>').append(data);
            element.parent().find('.dropdown-menu').append(test);

        });

    }

    return {
        restrict: 'A',
        link: link,
        scope: true,
        transclude: true
    }

});

app.directive('arBootstrapSelectOption', function ($compile) {
    function link(scope, element, attrs) {
        //scope.arBootstrapSelectOptions.push([attrs.value, $compile(attrs.content)(scope)]);
        scope.$emit('arBootstrapSelectNewItem', $compile(attrs.content)(scope));

    }

    return {
        scope: true,
        restrict: 'A',
        link: link
    }

});
})();
(函数(){
"严格使用",;
var app=角度模块('mainApp');
app.directive('arBootstrapSelect',函数($interval,$compile){
//$scope.arbotStrapSelectOptions=[];
功能链接(范围、元素、属性){
//元素。隐藏();
作用域:$on('arBootstrapSelectNewItem',函数(事件、数据){
var测试=$(“
  • ”)。追加(数据); element.parent().find('.dropdown menu').append(test); }); } 返回{ 限制:“A”, 链接:链接, 范围:正确, 转移:对 } }); 应用指令('arBootstrapSelectOption',函数($compile){ 功能链接(范围、元素、属性){ //推送([attrs.value$compile(attrs.content)(scope)]; 范围$emit('arBootstrapSelectNewItem',$compile(attrs.content)(范围)); } 返回{ 范围:正确, 限制:“A”, 链接:链接 } }); })();
    我不完全理解您的具体示例,因此我将从概念层面回答

    似乎在较高的层次上,您只想为
    ng repeat
    (例如
    )指定一个用户提供的模板,并将其放置在指令提供的模板中(例如
  • 将模板作为内容提供,而不是作为属性提供,将更容易、更友好。然后,您需要做的就是将内容转写出来。(我在这里避免使用
    ,因为它本身就是一个指令,我不太明白您想做什么-我将使用
    ):


    您是否试图用自定义选择替换/扩充
    ?就本问题而言,
    重要吗?如果不是,你能减少这个例子吗?我建议删除任何不相关的内容(样式、控件、标记)。请举例说明您希望最终结果是什么样的。此外,错误似乎与插值有关-您是否确定它在您发布的代码中(例如,不在
    arCountry
    指令中)?底线是,我正在编译指令并将其以编译状态存储在列表中。如何使用ng repeat加载?同样,太宽。我可以试着给你一个解决方案,但如果不了解你的确切问题,它可能会偏离目标。和。准确地说,您存储的是一个已编译和链接的元素。一旦有了这些元素,就可以迭代并将它们放入DOM中——当然,这将不必要地重新创建
    ng repeat
    正在做的事情
    (function () {
    'use strict';
    var app = angular.module('mainApp');
    
    app.directive('arBootstrapSelect', function ($interval, $compile) {
        $scope.arBootstrapSelectOptions = [];
    
        function link(scope, element, attrs) {
            //element.hide();
    
        }
    
        return {
            restrict: 'A',
            link: link,
            scope: true
        }
    
    });
    
    app.directive('arBootstrapSelectOption', function ($compile) {
        function link(scope, element, attrs) {
            scope.arBootstrapSelectOptions.push([attrs.value, $compile(attrs.content)(scope)]);
        }
    
        return {
            scope: true,
            restrict: 'A',
            link: link,
        }
    
    });
    })();
    
    (function () {
    'use strict';
    var app = angular.module('mainApp');
    
    app.directive('arBootstrapSelect', function ($interval, $compile) {
        //$scope.arBootstrapSelectOptions = [];
    
        function link(scope, element, attrs) {
            //element.hide();
    
            scope.$on('arBootstrapSelectNewItem', function (event, data) {
                var test = $('<li></li>').append(data);
                element.parent().find('.dropdown-menu').append(test);
    
            });
    
        }
    
        return {
            restrict: 'A',
            link: link,
            scope: true,
            transclude: true
        }
    
    });
    
    app.directive('arBootstrapSelectOption', function ($compile) {
        function link(scope, element, attrs) {
            //scope.arBootstrapSelectOptions.push([attrs.value, $compile(attrs.content)(scope)]);
            scope.$emit('arBootstrapSelectNewItem', $compile(attrs.content)(scope));
    
        }
    
        return {
            scope: true,
            restrict: 'A',
            link: link
        }
    
    });
    })();
    
    <my-option ng-repeat="c in countries">
      <ar-country country-id='{{$index}}'></ar-country>
    <my-option>
    
    .directive("myOption", function(){
      return {
        scope: true,
        transclude: true,
        template: '<li ng-transclude></li>'
      }
    });
    
    <my-option>
      <li><ar-country country-id="0"></ar-country></li>
    </my-option>
    <my-option>
      <li><ar-country country-id="1"></ar-country></li>
    </my-option>
    ..
    
    <my-select>
      <my-option ng-repeat="c in countries>
        <ar-country country-id='{{$index}}'></ar-country>
      </my-option>
    </my-select>
    
    .directive("mySelect", function(){
      return {
        scope: true,
        transclude: true,
        template: '<h1>heading</h1><div ng-transclude></div>',
        controller: function(){
          // this can be called by the child
          this.registerChild = function(childElement, childController){
            // store the children, if needed
          }
        }
      }
    });
    
    .directive("myOption", function(){
      return {
        scope: true,
        transclude: true,
        template: '<li ng-transclude></li>'
        require: ['myOption', '^mySelect'],
        controller: function(){
          // you can define some functions here
        },
        link: function(scope, element, attrs, ctrls){
          var me = ctrls[0], 
              selectCtrl = ctrls[1];
    
          selectCtrl.registerChild(element, me);
      }
    });