用于查找关联数组的AngularJS指令

时间:2017-06-20 14:23:07

标签: javascript angularjs arrays

我正在尝试制作一个AngularJS指令,该指令从作为指令属性提及的键应该返回一个html模板,其中包含与作用域数据包含的关联数组相对应的字符串。

我认为代码片段会更清晰:

范围内的我的关联数组:

{"mapData":
    {"menu1":"Apples",
    "menu2":"Strawberries"}}

如何调用该指令:

<div ng-controller="menuAngularController">
    <menu-dir menuData="menu1"></menu-dir>
</div>

角度解释后应返回的HTML:

<li dropdown class='dropdown dropdown-fw'>
     <a href='#' class='dropdown-toggle' dropdown-toggle>Apples 
            <span class='caret'></span>
     </a>
     <ul class='dropdown-menu' role='menu' ng-transclude></ul>
</li>

我正在制定的指令,没有令人信服的结果:

angular.module('Module.Directives',[]).directive('menuDir', function(){
    restrict:'E',
     ̶t̶r̶a̶n̶c̶l̶u̶d̶e̶ transclude:true,
    replace:true,
    scope:{
         menuData:'@'
    },
    template :"<li dropdown class='dropdown dropdown-fw'><a href='#' class='dropdown-toggle' dropdown-toggle>"+ 
            "{{test}} <span class='caret'></span></a>"+
            "<ul class='dropdown-menu' role='menu' ng-transclude></ul></li>",

    link:function(scope, elem, attrs, controllers ̶,̶ ̶$̶s̶c̶o̶p̶e̶ ) {
        //I put $watch because my AngularJS controller load data from an external service, so I listen change on data loaded
        scope.$watch('menuData', function(newValue, oldValue){
                //I get the data of the array by the id
                scope.test = "{{mapData['"+newValue+"']}}";
       });
   });

角度控制器:

angular.module('MenuAngular.Controller', [])
.controller('menuAngularController', MenuAngularController);    
    MenuAngularController.$inject = ['menuAngularServices', '$scope'];
    function MenuAngularController(menuAngularServices, $scope){
        //the service (tested, all is ok on this side) that return the data on a map
        menuAngularServices.initMenu.query({},function(data){
            $scope.mapData= data.mapMessages;
        },
        function(error){
            console.log(error);
        });

实际上,我成功地在屏幕上打印了“{{mapData [menu1]}}”,但没有被Angular的值取代。

有没有人有想法? (对不起我的英语水平,提前谢谢你!)

2 个答案:

答案 0 :(得分:1)

第一件事:在指令

中传递$scope.mapData

视图:

<menu-dir menu-data="menu1" map-data="mapData"></menu-dir>

指令:

scope:{
     menuData: '@',
     mapData: '='
},

第二件事:更改scope.test分配:

scope.test = "{{mapData['"+newValue+"']}}"是创建string的作业。事实上这就是你所看到的!

您只需:scope.test = menuData[newVal];

答案 1 :(得分:0)

指令属性需要标准化为kebab-case

<!-- ERRONEOUS
<div ng-controller="menuAngularController">
    <menu-dir menuData="menu1"></menu-dir>
</div>
-->

<!-- BETTER -->
<div ng-controller="menuAngularController">
    <menu-dir menu-data="menu1"></menu-dir>
</div>

有关详细信息,请参阅AngularJS Developer Guide - Directive Normalization

更新

由于该指令使用 isolate 作用域,因此指令作用域不会从父作用域继承数据。必须使用绑定定义来自父作用域的所有数据:

<menu-dir menu-data="menu1" map-data="mapData"></menu-dir>

此外,无需使用观察者,只需将Angular Expression放在指令模板中:

app.directive('menuDir', function(){
    restrict:'E',
    transclude:true,
    //replace:true, //REPLACE is DEPRECATED

    scope: {
         menuData:'@',
         //ADD mapData one-way binding
         mapData: '<'
    },
    //ADD {{test}} expression to template
    template: `
        <li dropdown class='dropdown dropdown-fw'>
           <a href='#' class='dropdown-toggle' dropdown-toggle> 
            {{mapData[menuData]}} <span class='caret'></span>
           </a>
           <ul class='dropdown-menu' role='menu' ng-transclude></ul>
        </li>`,

    link: function(scope, elem, attrs) {
        //I put $watch because my AngularJS controller load data from an external service, so I listen change on data loaded
        /* REMOVE watcher
        scope.$watch('menuData', function(newValue, oldValue){
                //I get the data of the array by the id
                scope.test = "{{mapData['"+newValue+"']}}";
       });*/
    }
});