2013-10-12 52 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一起使用(再添加一個元素),它會起作用!