2013-10-12 47 views
0

我在一个我为下拉替换写的指令中有一个非常奇怪的行为。使用的模型可以使用子节点无限嵌套。 (HAML-Code):AngularJS:指令的模板不能正确渲染

.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" } 

正如我到目前为止所遇到的,该模型的行为是绝对正确的!在调试视图中或者通过console.log或者$ log whatever,但是指令的渲染会变得混乱起来,显示项目翻倍或者甚至倍增,取决于您切换下拉的次数。

咖啡剧本是这样的,这是很容易的代码:该指令的

# 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 

    } 
] 

视图模板代码得到由它写在HAML,看起来像这样的轨道控制器 交付。它采用无限嵌套如果存在子节点:

.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'" } 

我没有与这只是一个问题的任何第二个下拉不正确地更新其观点,型号不对。我想知道你能不能帮助或看到一些不合法的东西。

亲切的问候, 亚历

+0

只是好奇,为什么你使用on-change而不是ng-change? – jpmorin

+0

我对HAML并不熟悉,但是按照你的缩进,这是我的理解:你首先在'ul'的内部循环'div',在'div'里面放置'li'。在你循环的'ul'上有'li'的兄弟,你在'ul'中使用'div'来启动下一个子级别......当我看到它时,你的层次结构如下所示: 'ul > DIV [循环]> [li>系统| UL [循环]> DIV> [li>系统| UL [循环]> DIV ...'。 AFAIK,这不是有效的HTML。 'ul'中唯一有效的元素是'li'。 – jpmorin

+0

我确实使用on-change,因为指令读取的值是在自定义作用域中调用的回调函数$ watch ...我不想混淆该指令的其他用户的ng-change,因为ng-change是原生指令... 是的,我知道这是不好的HTML。原因是增加了一些能够接收正确项目的块。我将在下面检查你的帖子。非常感谢。 – sp33c

回答

1

编辑:改性plunker(http://plnkr.co/edit/h6XdT5w0JRlVIQfxjByn?p=preview)用与子菜单(使用自举2.3.2和角度UI 0.5.0)的下拉菜单显示的数据。

继我对你的问题的评论:

我做的HTML标签是如何嵌套获得有效的HTML一些修正。我从你在另一个SO问题(angularjs: force re-rendering/ full refresh a directive template)中提到的重击者那里获得了你的消息。

这里有一个现场演示:http://plnkr.co/edit/JTt3moub2haMGxH65YtK?p=preview

我也参加了一旁的node.html模板在它自己的文件,而不是script符号的如果不是在正确的地方使用,可能会导致问题。当你点击一个项目时,它被正确设置为当前值。

template.html

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

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> 

分层数据

$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'} 
    ]} 
    ]} 
]; 

看怎么祛瘀编辑div不应嵌套在ul元素内。

+0

我认为你不应该使用属性名称'ng-model',如果你没有使用它,就像它应该在你的指令中一样。尝试命名它别的东西,它可能有助于避免奇怪的错误。 – jpmorin

+0

嗨。我刚刚检查过,看到你的解决方案的行为仍然相同 - 视图不会以正确的方式更新。 https://dl.dropboxusercontent.com/u/21600359/Bildschirmfoto%202013-10-13%20um%2003.48.12.png 非常感谢你,真的对你有所帮助。 – sp33c

+0

为什么我的html被搞砸的原因是,ng-click将注意的元素需要被隔离,而不是与另一个ng-clicks嵌套,以防止许多同时被触发。 (角度有时真的面对w3c规范实现的东西,我们应该需要注意,因为它不知道它是否已经可用) 这里是第二个问题的屏幕截图 https://dl.dropboxusercontent.com/u/21600359 /Bildschirmfoto%202013-10-13%20um%2003.48.23.png – sp33c

1

如果您有相互嵌套的NG-重复也许它呈现奇怪的理由是,你正在使用中相互重复相同的名称。如果你这样做,你实质上会在你沿着DOM树向前进时覆盖引用。

+0

嗨,这是无限递归技巧 - 实际上,它工作到非指令代码。谢谢。 – sp33c

0

问题是ng-include不更新。如果与ng-if一起使用(再添加一个元素),它会起作用!