简体   繁体   English

AngularJS:指令的模板无法正确呈现

[英]AngularJS: directive's template is not rendering correctly

I have a really strange behavior in a directive I wrote for a dropdown replacement. 我在为下拉列表替换编写的指令中有一个非常奇怪的行为。 the model used can be nested infinitely using child nodes. 使用的模型可以使用子节点无限嵌套。 the directive is included like this (HAML-Code): 该指令包含在内(HAML-Code):

.control-group
  -# use the angular directive "dropdown-tree" that can handle unlimited nested models!
  .controls{ "dropdown-tree" => "", "ng-model" => "categories_as_tree", "current-value" => "currentCategory", "dropdown-placeholder" => "choose category", "ng-disabled" => "!categories || categories.length==0", "on-change"=>"fetchProducts(category)" }

%h4 Products
.control-group
  .controls{ "dropdown-tree" => "", "ng-model" => "products_as_tree", "current-value" => "currentProduct", "dropdown-placeholder" => "choose product", "ng-disabled" => "!products || products.length==0" }

As I encountered so far, the model is behaving absolulately correctly! 正如我到目前为止遇到的那样,该模型表现得非常正确! in debug view or via console.log or $log whatever, but the rendering of the directive gets messed up showing the items doubled or even multiplied, dependent on how many times you switch the dropdown. 在调试视图中或通过console.log或$ log中的任何内容,但指令的呈现变得混乱,显示项目加倍或甚至成倍增加,具体取决于您切换下拉列表的次数。

the coffee script looks like this, which is easy code: 咖啡脚本看起来像这样,这很简单:

# use array -> being resistend against uglifiers mangle
mymodule.directive 'dropdownTree', [ ->
  return {
    templateUrl: '/angular/templates/dropdown_tree'
    ,
    #require: 'ngModel', # don't need that so far, we keep things simple!
    scope: {
      ngModel: '=',
      dropdownPlaceholder: '@',
      currentValue: '=',
      ngDisabled: '=',
      onChange: '&'
    },
    link: (scope, element, attr, ngModelCtrl) ->

      # fake the ng-change
      scope.$watch('currentValue', ->
        scope.onChange()
      , true)

      scope.selectValue = (value) ->
        scope.currentValue = value

  }
]

the view template code of the directive gets delivered by an rails controller it is written in HAML and looks like this. 指令的视图模板代码由rails控制器提供,它是用HAML编写的,看起来像这样。 it uses infinite nesting if the child nodes exist: 如果子节点存在,它使用无限嵌套:

.btn-group{ :name => "FIXME", "ng-required" => "true" }
  %a.btn.btn-default.dropdown-toggle{ "data-toggle" => "dropdown", href: "#", "ng-disabled"=>"ngDisabled" }
    {{currentValue.name || dropdownPlaceholder }}
    %span.caret
  %ul.dropdown-menu{ "ng-show" => "!ngDisabled" }
    %div{ "ng-repeat" => "model in ngModel", "ng-include" => "'node.html'" }

%script{ :type => "text/ng-template", :id => "node.html" }
  %li{ "ng-click" => "selectValue(model)" }
    %a
      {{model.name}}
  %ul{ "ng-repeat" => "model in model.children", :style => "margin-left: 10px;" }
    %div{ "ng-include" => "'node.html'" }

I did not have any problems with this only the one the second dropdown does not update its view correctly, the model does. 我没有遇到任何问题只有第二个下拉列表没有正确更新其视图,模型确实如此。 I wonder if you can help or see something which is no legitimate. 我想知道你是否可以帮助或看到一些不合法的东西。

kind regards, Alex 亲切的问候,Alex

If you have nested ng-repeats within each other maybe the reason it's rendering strangely is that you are using the same names for the repeats within each other. 如果你在彼此之间嵌套了ng-repeats,那么它奇怪地呈现的原因是你在彼此之间使用相同的名称进行重复。 If you do this you essentially override the reference as you progress down the DOM tree. 如果执行此操作,则在沿DOM树向下进行时基本上覆盖引用。

EDIT: Modified plunker ( http://plnkr.co/edit/h6XdT5w0JRlVIQfxjByn?p=preview ) with data displayed in a dropdown menu with sub menus (using bootstrap 2.3.2 and angular-ui 0.5.0). 编辑:修改了plunker( http://plnkr.co/edit/h6XdT5w0JRlVIQfxjByn?p=preview ),数据显示在带有子菜单的下拉菜单中(使用bootstrap 2.3.2和angular-ui 0.5.0)。

Following my comment on your question: 在我对您的问题发表评论后:

I did some correction on how the html tags are nested to obtain valid html. 我对如何嵌套html标签以获取有效的html做了一些修改。 I took your source from a plunker you mentionned in another SO question ( angularjs: force re-rendering/ full refresh a directive template ). 我从你在另一个SO问题中提到的一个plunker中获取了你的源代码( angularjs:强制重新渲染/完全刷新指令模板 )。

Here is a live demo: http://plnkr.co/edit/JTt3moub2haMGxH65YtK?p=preview 这是一个现场演示: http//plnkr.co/edit/JTt3moub2haMGxH65YtK?p = preview

I also took aside the node.html template in its own file instead of the script notation that can cause problems if not used at the right place. 我还将node.html模板放在自己的文件中,而不是script符号,如果没有在正确的位置使用,可能会导致问题。 When you click on an item, it is correctly set as the current value. 单击某个项目时,它会正确设置为当前值。

template.html template.html

<ul class='dropdown-menu' ng-show='!ngDisabled'>
    <li ng-include="'node.html'" ng-repeat='model in ngModel'></li>
  </ul>

node.html node.html

<a href="#" ng-click='selectValue(model)'>{{model.name}}</a>
<ul>
  <li ng-include="'node.html'" ng-repeat='model in model.children'></li>
</ul>

hierarchical data 分层数据

$scope.products = [
  {name: 'Product1', children: [
    {name:'Product1.1', children: [
      {name:'Product1.1.1'}
    ]},
    {name:'Product1.2', children: [
      {name:'Product1.2.1'},
      {name:'Product1.2.2'},
      {name:'Product1.2.3', children: [{name:'Product1.2.3.1'}]},
      {name:'Product1.2.4'}
    ]}
  ]},
  {name: 'Product2', children: [
    {name:'Product2.1', children: [
      {name:'Product2.1.1'},
      {name:'Product2.1.2'}
    ]},{name:'Product2.2', children: [
      {name:'Product2.2.1'},
      {name:'Product2.2.2'},
      {name:'Product2.2.3'}
    ]}
  ]}
];

Look how I removed the div that should not be nested inside an ul element. 看看我如何删除不应嵌套在ul元素中的div

the issue is that ng-include does not update. 问题是ng-include不会更新。 if using with ng-if (adding one more element) it works! 如果使用ng-if(添加一个元素)它可以工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM