在AngularJS中创建具有重复指令结构的唯一ID



所以这有点复杂,我将尝试彻底解释它。最终,我想回答的问题是,"我如何在HTML中打印模型,而不是模型的值?"我相信答案会解决我的问题,但我将全面讨论我的问题。这样你们就可以告诉我,我可能做错了。在这种情况下,我有很多重写工作要做,所以我希望不会。

场景:这是初始HTML页面,其中"field"是一个自定义指令。

<field model="model1" placeholder="Model 1" type="input"></field>
<field model="model2" placeholder="Model 2" type="input"></field>
<field model="model3" placeholder="Model 3" type="input"></field>

这是自定义指令。

app.directive("Field", function(){
  return{
    restrict: "E",
    scope: { model: '=', placeholder:'@', type: '@'},
    templateUrl: function(tElement, tAttrs){
      return 'views/common/' + tAttrs.type + '.html';
    }
  };
});

这是指令的模板。type属性只是在不同的模板中提供,这样我就不必做复杂的if-then结构。请耐心等待,它可能会变得有点复杂。

<field-label model="model">{{placeholder}}</field-label>
<div class="col-sm-2 no-right-pad">
    <input type="text" ng-model="model.value" placeholder="{{placeholder}}" class="form-control input-sm"></input>
</div>
<div class="col-sm-2 no-pad">
  <field-options field-options-model="model" class="field-options"></field-options>
</div>

正如你所知道的,这是一个表单。每个初始指令调用都会创建一个表单组,其中包含一个标签、一个输入和一个指令,使用这些指令可以将选项添加到模型中。为了这个练习,假设我希望能够为每个输入添加一个注释。当你进入字段选项指令时,我有点脏了,我更改了模型名称,这是以前尝试的遗留问题,没有造成任何伤害,但我仍然可能更改它。我不一定需要它,因为指令是嵌套的,因此共享$scopes。这是指令:

app.directive("FieldOptions", function() {
  return {
    restrict: "E",
    scope: { field: '=FieldOptionsModel' },
    templateUrl: 'views/common/field-options.html'
  };
});

这个模板:

<div class="dropdown">
  <a ng-href class="dropdown-toggle btn btn-bars" data-toggle="dropdown" tabindex="-1"><i class="fa fa-bars"></i></a>
  <ul class="dropdown-menu pull-right">
    <li><a data-toggle="modal" href="#{{field}}-comment-modal">Add Comment</a></li>
  </ul>
</div>
<div id="{{field}}-comment-modal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h3>Submit Comment</h3>
      </div>
      <div class="modal-body">
        <div class="form-group">
          <label class="control-label">Add Comment</label>
          <textarea ng-model="field.comments[0].comment" class="form-control"></textarea>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-warning" data-dismiss="modal">Cancel</button>
        <button class="btn btn-primary" data-dismiss="modal" href="#">Add Comment</button>
      </div>
    </div>
  </div>
</div>

好吧,如果你不知道的话,我的字段选项是一个带有下拉菜单的按钮,可以选择弹出菜单。因为我们有重复的指令,所以您可以立即判断出,目前DOM结构中存储的这个弹出窗口基本上有3个相同的副本。1用于Model1,1用于Model2,1用于Model 3。我们现在遇到了一个问题,无法为每个字段组调用正确的弹出窗口。由于它通常是用相同的ID构建的,所以有3个相同的ID,浏览器无法处理,所以只打开第一个。正如您在这里看到的,我的解决方案是调用模型名称,并将其注入注释弹出窗口的ID中,从而使其在每个字段组中都是唯一的。问题是id="{{field}}-comment modal"并没有像我希望的那样打印出id="model1 comment modal,而是打印出了id="{"value"="任何可能设置的值,或者如果我们在填写输入之前单击添加注释,则打印为空。"}-comment modal"

我回到我最初的问题,"我如何打印模型字符串,而不是它所代表的数据?"或者,我做错了什么,或者如何停止担心并找到一份新工作。

注意:请绅士一点,我的例子比较笨,实际使用起来比较复杂和重复。

不确定是否可以输出变量名,但您的问题可以通过以下解决方案之一解决:

  1. 将"name"属性添加到模型对象中,并使用它生成ID或
  2. 将名为"name"的新参数传递到第一个目录,并将其传播到内部目录。无论如何,您已经使用了标准属性,如占位符和类型或
  3. 创建一个工厂,负责为整个应用程序生成唯一ID,或者
  4. 只需使用时间戳Date.now()作为模式ID的前缀

希望这会有所帮助。

更新:经过一点挖掘,可以使用指令链接函数的第三个属性从第一个指令中检索字符串model1、model2:

<field model="model1" placeholder="Model 1" type="input"></field>
angular.module('app', []).directive("field", function() {
  return {
    restrict: "E",
    scope: { model: '=', placeholder:'@', type: '@'},
    templateUrl: function(tElement, tAttrs){
      return 'views/common/' + tAttrs.type + '.html';
    },
    link: function(scope, elem, attrs) {
      console.log(attrs.model);
      //Will output model1
    }
  }
});

通过将此字符串转发到内部指令,您可以生成唯一的ID

最新更新