在Angular指令

时间:2015-12-17 10:41:10

标签: javascript angularjs

我正在实现一个控件/窗口小部件,它有三个选项,只能选择其中一个,这使我使用了radiobuttons。这个小部件必须在各种表单上出现几次,所以我开始创建(递增)专用指令。

该指令的模板如下:

<div class="row">
<span class="fieldlabel col-xs-3">{{title}}</span>
<div>
    <label>
        <input type="radio" data-ng-model="modelName" value="{{value1}}">
        {{label1}}
    </label>
    <label>
        <input type="radio" data-ng-model="modelName" value="{{value2}}">
        {{label2}}
    </label>
    <label>
        <input type="radio" data-ng-model="modelName" value="{{value3}}">
        {{label3}}
    </label>
</div>

通过使用自定义指令或在控制器中正确定义/计算标题,标签和值。

我现在面临的最后一个问题是如何为每个这样的小部件指定不同的模型绑定?此小部件的所有实例当前都共享其模型绑定,这当然不是我需要的。例如,下面虚构示例中的两个div都将绑定到&#34; modelName&#34;但我需要他们绑定说&#34; annotationsPos&#34;和&#34; menuPos&#34;在视图的控制器中。

<div my-3option-radiobutton title="Show annotations"></div>
<div my-3option-radiobutton title="Menu position"></div>

如何在自定义指令中指定绑定?

编辑1 我想我要么自己清楚,要么缺少一些可以帮助我理解答案的元素。

如果我手工编写HTML,我会得到类似的东西:

<div class="row">
<span class="fieldlabel col-xs-3">Position of your annotations</span>
<div>
    <label>
        <input type="radio" data-ng-model="annotationsPos" value="left">
        Left of the element
    </label>
    <label>
        <input type="radio" data-ng-model="annotationsPos" value="middle">
        Through the element
    </label>
    <label>
        <input type="radio" data-ng-model="annotationsPos" value="right">
        Right of the element
    </label>
</div>
<!-- -->
<div class="row">
<span class="fieldlabel col-xs-3">Position of the top menu</span>
<div>
    <label>
        <input type="radio" data-ng-model="menuPos" value="left">
        Top left
    </label>
    <label>
        <input type="radio" data-ng-model="menuPos" value="middle">
        Top middle
    </label>
    <label>
        <input type="radio" data-ng-model="menuPos" value="right">
        Top right
    </label>
</div>
<!-- -->
<div class="row">
<span class="fieldlabel col-xs-3">Position of notifications</span>
<div>
    <label>
        <input type="radio" data-ng-model="notificationPos" value="left">
        Bottom left
    </label>
    <label>
        <input type="radio" data-ng-model="notificationPos" value="middle">
        Bottom middle
    </label>
    <label>
        <input type="radio" data-ng-model="notificationPos" value="right">
        Bottom right
    </label>
</div>

我没有多次复制和粘贴此样板代码,而是希望通过属性指令来执行此操作:

<div my-3option-radiobutton title="Position of your annotations"></div>
<div my-3option-radiobutton title="Position of system notifications"></div>
<div my-3option-radiobutton title="Position of the top menu"></div>

这些块之间的更改由标题,值和最重要的模型属性值组成。我以非优雅的方式覆盖了指令控制器中的标题和值(请参阅下面的插件)。我的问题是我似乎无法:

  1. 确定在何处指定ng-model AND
  2. 生成&#34;生成&#34; HTML代码正确引用该模型属性值(即&#39; annotationPos&#39;,&#39; notificationsPos&#39;和&#39; menuPos&#39;)和
  3. 与父控制器进行双向绑定
  4. 编辑2 这个plunk表明@Suresh的答案正在起作用,对字段名称进行了一些小修改。但是,directive that I have written不起作用(页面上的所有小部件都绑定到相同的值),可能是因为它是属性指令而不是元素指令。我不想拥有后一种类型,因为它对我没有意义并且最重要的是,这将被集成到现有的大型项目中,其他开发人员使用它,不使用任何元素指示。然而,这并不意味着永远不会在项目中使用元素指令。

    无论如何,我一直在寻找解决方案。感谢。

    编辑3 我已经在模板中使用了ng-repeat指令,就像@Suresh一样。使用开发的模板(即手动重复输入标签)不起作用,但我不知道这是否与使用/不使用ng-repeat有关,或者更确切地说是与我&#34;构建&#34;控制器中的值和标签。

    从我的插件中吸取的教训:即使在小部件的控制器中使用ngModel(下面)进行双向绑定:

    • 除非使用ng-repeat,否则页面上的所有控件都将绑定到相同的值/变量
    • 如果模板具有data-ng-model="ngModel"而不是data-ng-model="$parent.ngModel",则不会更新父控制器的绑定模型
    scope: {
        ngModel: "="
    }
    

2 个答案:

答案 0 :(得分:2)

'use strict';
var app = angular.module('MyApp',[]);
app.directive("myRadiobutton", function () {
    var templateHtml = function () {
        return '<div class="form-group" >' +
                 '<label style="margin-right: 10px"; ng-repeat="(key, option) in options.valueList">' +
                         '<input type="radio" name="myfield" ng-value="option.value" ng-model="$parent.ngModel" ng-required="options.required" />{{option.title}}' +
                 '</label>' +
             '</div>';
    };

    return {
        scope: { options: '=', ngModel: '=' },
        required: ['ngModel'],
        restrict: 'E',
        template: templateHtml,
    };
});
app.controller('myController', function ($scope) {
    $scope.radioGender =   {
    "label": "Gender",
    "required": true,
    "className": "",
    "valueList": [
      {
        "title": "Male",
        "value": "1"
      },
      {
        "title": "Female",
        "value": "2"
      },
      {
        "title": "Others",
        "value": "3"
      }
    ]

  };
  
  })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="myController" >
   <my-radiobutton options="radioGender" ng-model="genderValue"></my-radiobutton>
  <span>{{genderValue}}</span>
</div>

答案 1 :(得分:0)

您应该在指令范围内使用“=”来绑定对象:

directives.directive("dirname", function () {
     return {
         restrict: 'A',
         replace: false,
         scope: {
             model: '=', // pass a referecne object
             title: '@'  // path as string
         },
         controller: function ($scope, $rootScope) {
             ...
         },

     }
 });


 <div dirname title="Menu Position" model="modelName" ></div>