Angular中有多个自定义指令范围

时间:2015-04-15 20:06:07

标签: angularjs angularjs-directive

我有一个自定义指令,我希望在页面上有多个元素。我很难隔离范围并根据子范围显示元素。以下是我正在尝试做的一个例子:

app.js:

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
})
.directive('comShowLabelOnFocus', function() {
  return {
    restrict: 'A',
    scope: {
      showlabel: '='
    },
    link: function(scope) {
      scope.inputClicked = function() {
        event.currentTarget.placeholder = '';
        scope.showlabel = true;
      };
    }
  }
});

的index.html:

<body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>


    <div class="form-group medium-6 columns" com-show-label-on-focus>
      <input  
        type="email"
        name="email"
        ng-model="model.email"
        placeholder="Your Email Address"
        ng-click="inputClicked()"/>
      <label ng-show="showlabel">Email Address (Required)</label>
      showlabel is: {{showlabel}}
    </div>

    <div class="form-group medium-6 columns" com-show-label-on-focus>
      <input  
        type="text"
        name="name"
        ng-model="model.name"
        placeholder="Your Name"
        ng-click="inputClicked()"/>
      <label ng-show="showlabel">Name (Required)</label>
      showlabel is: {{showlabel}}
    </div>
  </body>

行动中:Plunker

基本上,当字段获得焦点时,字段标签应该出现。如果我在指令中注释掉范围声明,则showlabel范围变量是根范围,并且出现BOTH标签。感谢。

1 个答案:

答案 0 :(得分:2)

首先,您期望div内的标记与其上的属性指令一样,就像指令的模板一样。这不会像你想要的那样工作。

让我们在您的指令对象的templatetemplateUrl中定义指令的标记:

return {
    //other properties
    template: '<input type="text" name="name" ng-model="model.name" placeholder="{{myPlaceholder}}" ng-click="inputClicked()"/> <label ng-show="showlabel">{{myLabel}}</label>showlabel is: {{showlabel}}',
}

接下来,设置范围以正确使用模板,并且不要绑定到showlabel。该指令可以在其孤立的范围内管理它:

scope: {
  myPlaceholder: '@',
  myLabel: '@'
}

最后,让我们看看Angular文档对于控制其模板的指令的restrict属性有什么说法:

  

我应该何时使用属性与元素?在创建控制模板的组件时使用元素。常见的情况是,您为模板的某些部分创建特定于域的语言。在使用新功能装饰现有元素时使用属性。

因此,由于您的指令确实控制了它的模板,因此您应该将其限制为元素。

最后你的指令javascript看起来像这样:

.directive('comShowLabelOnFocus', function() {
  return {
    restrict: 'E',
    scope: {
      myPlaceholder: '@',
      myLabel: '@'
    },
    template: '<input type="text" name="name" ng-model="model.name" placeholder="{{myPlaceholder}}" ng-click="inputClicked()"/> <label ng-show="showlabel">{{myLabel}}</label>showlabel is: {{showlabel}}',
    link: function(scope) {
      scope.showlabel = false;
      scope.inputClicked = function() {
        event.currentTarget.placeholder = '';
        scope.showlabel = true;
      };
    }
  }
});

这样的标记:

<com-show-label-on-focus data-my-placeholder="Your Name" data-my-label="Name (Required)"></com-show-label-on-focus>

And here is your plunker modified and demonstrating this implementation

我为所有修改道歉,我最初误解了你的问题。