【问题标题】:Angular directive attributes aren't being passed throughAngular 指令属性没有被传递
【发布时间】:2014-03-26 04:07:26
【问题描述】:

我试图通过为每个元素制作指令来缩短我的表单代码,但是我的指令没有显示我传递给它的任何内容,并且模型没有被绑定。

HTML:

<formstring dataBinding="project.title" dataTitle="Title" dataPlaceholder="title" />

指令:

app.directive('formstring', function () {
  return {
    restrict: 'AEC',
    dataBinding: '=',
    dataTitle: '@dataTitle',
    dataPlaceholder: '@dataPlaceholder',
    dataHelp: '@dataHelp',
    templateUrl: '/app/js/directives/form/string.html',
  };
});

字符串.html:

<div class="form-group">  2   <label for="{{dataTitle}}" class="col-sm-2 control-label">{{dataTitle}}</label    >
  <div class="col-sm-10">
    <input type="text" class="form-control" id="{{dataTitle}}" placeholder="{{da    taPlaceholder}}" ng-model="dataBinding">
    <p ng-show="dataHelp" class="help-block">{{dataHelp}}</p>
  </div>
</div>

project 是一个具有“title”属性的 $scope 对象。

我错过了什么?为什么在没有填写任何属性的空白输入中会出现这种情况?为什么绑定不起作用?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    您还没有理解指令是如何正确配置的。我建议你阅读文档,它可以帮助你更好地理解。

    与此同时,您的 HTML、指令代码和模板应如下所示(还有一个 working demonstration on Plunkr):

    HTML:

    <formstring data-binding="project.title" 
                data-title="Title Demo" 
                data-placeholder="title placeholder"
                data-help="My help text">
    </formstring>
    

    指令:

    app.directive('formstring', function () {
      return {
        restrict: 'E',
        scope: {
            binding: '=',
            title: '@',
            placeholder: '@',
            help: '@'
        },
        templateUrl: '/app/js/directives/form/string.html',
      };
    });
    

    模板(string.html):

    <div class="form-group">
       <label for="{{title}}" class="col-sm-2 control-label">
          {{title}}
        </label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="{{title}}" placeholder="{{placeholder}}" ng-model="binding">
          <p ng-show="help" class="help-block">{{help}}</p>
        </div>
    </div>
    

    【讨论】:

    • 请注意,Angular 会删除每个属性中前导的data-,详情请参阅Directive Guide
    • 确保更改模板以引用不带data 前缀(当然是小写)的范围属性。
    • @JasonMcCarrell 我更新了我的答案以证明它应该是什么。甚至还有一个工作 plunkr 供您自己尝试。
    • 嗯,你肯定有我的例子的工作 plunkr,但它仍然无法在我的最终工作,所以我需要尝试更加努力地查看差异。一旦我弄清楚差异,我会回复你。到目前为止非常感谢!
    • 显然我需要去掉前缀。所以标题,而不是 string.html 模板中的 dataTitle。谢谢!我猜我遇到这么困难的原因是因为我使用了数据前缀。
    【解决方案2】:

    您需要更改创建隔离范围的方式:

    app.directive('formstring', function () {
      return {
        restrict: 'AEC',
        scope: {
           dataBinding: '=',
           dataTitle: '@dataTitle',
           dataPlaceholder: '@dataPlaceholder',
           dataHelp: '@dataHelp'
        },
        templateUrl: '/app/js/directives/form/string.html',
      };
    });
    

    阅读the doc 了解有关隔离/隔离范围含义的详细信息,因为它会影响整个范围。

    编辑: 我之前没有注意到这个额外的问题。当您使用指令时,您的驼峰式范围属性会变成蛇形(请参阅 Mobin 的回答):

    <formstring data-binding="project.title" data-title="Title" data-placeholder="title" />
    

    但是,在您的模板中,属性仍然是驼峰式的:

    <div class="form-group">  2   <label for="{{dataTitle}}" class="col-sm-2 control-label">{{dataTitle}}</label    >
      <div class="col-sm-10">
        <input type="text" class="form-control" id="{{dataTitle}}" placeholder="{{da    taPlaceholder}}" ng-model="dataBinding">
        <p ng-show="dataHelp" class="help-block">{{dataHelp}}</p>
      </div>
    </div>
    

    这是因为模板中的绑定是 JSON 属性,而使用指令属性时的属性是 XML 属性。

    我会对您的模板进行一些小调整,例如id="{{dataTitle}}" 可以轻松破坏要求 id 属性是唯一的 HTML 标准……您可能想改用name="{{dataTitle}}"name 仍然会导致问题,但不会破坏 document.getElementById 的例子。

    另外,我会尽可能使用ng-bind

    <p ng-show="dataHelp" class="help-block" ng-bind="dataHelp"></p>
    

    【讨论】:

    • 嗯,您说得对,我应该使用隔离范围,但即使您建议更改,仍然没有任何显示。
    • 哦。我之前回答时没有注意到,xml 不允许驼峰式大小写,因此您的范围内的dataBinding 必须在您的视图中声明为data-binding=""。为了清楚起见,我会更新答案。
    • 我只是做错了,因为我担心 data- 会被保留并把事情搞砸......它是 =P。我需要删除 data- 前缀,然后一切都按照上面 Greg 的建议进行。您的回答也很好,因为它提醒我使用隔离范围。谢谢!
    • 啊,是的,如果您的作用域的属性是dataBinding,我想您必须输入data-data-binding。我应该从一开始就认识到这一点。 :D
    【解决方案3】:

    应该是

    <formstring data-binding="project.title" data-title="Title" data-placeholder="title" />
    

    .

    【讨论】:

      猜你喜欢
      • 2017-06-20
      • 1970-01-01
      • 2015-10-27
      • 2019-09-22
      • 2016-05-10
      • 1970-01-01
      • 2023-04-05
      • 2014-04-03
      • 2015-11-29
      相关资源
      最近更新 更多