2015-04-25 49 views
0

我想創建一個指令,該指令可以使用AngularJS的遞歸樹結構,其中每個節點都可以在transclude部分中有自己的模板。無法替換ng模板中的元素

這裏是JS:

var app = angular.module('plunker', []); 
app.controller('MainCtrl', function($scope) { 
    $scope.input = [{ 
    name: 'blueberry cheesecake', 
    color: 'blue', 
    children: [{ 
     name: 'blueberry cheesecake', 
     color: 'blue' 
    }, { 
     name: 'rocky road', 
     color: 'mostly brown' 
    }] 
    }, { 
    name: 'rocky road', 
    color: 'mostly brown' 
    }]; 
}); 
app.directive("auratree", function() { 
    return { 
    scope: { 
     input: "=" 
    }, 
    template: function(element) { 
     element.data("customListTemplate", element.find("item-template")); 
     var c = 
     '<script type="text/ng-template" id="auratree2">' + 
     '<item-placeholder></item-placeholder>' + 
     '  <div ng-if="item.children">' + 
     '   <div ng-repeat="item in item.children" ng-include="' + 
     "'" + 'auratree2' + "'" + '">' + 
     '   <item-placeholder></item-placeholder></div>' + 
     '  </div>' + 
     '</script>' + 
     '<div ng-repeat="item in input" ng-include = "' + "'" + 'auratree2' + "'" + '">' + 
     '</div>'; 
     console.log(c); 
     return c; 
    }, 
    compile: function(tElement, tAttrs) { 
     var template = tElement.data("customListTemplate"); 
     tElement.find("script").html(tElement.find("script").html().replace("<item- placeholder></item-placeholder>", template.html())); 
    } 
    }; 

    function link(scope, element, attrs) {} 
}); 

下面是HTML

<!DOCTYPE html> 
<html ng-app="plunker"> 
    <head> 
    <meta charset="utf-8" /> 
    <title>Aura Tree</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.13/angular.js" data-semver="1.3.13"></script> 
    <script src="auratree.js"></script> 
    </head> 
<body ng-controller="MainCtrl"> 
    <pre>template 1:</pre> 
    <auratree input="input"> <item-template> 
    {{$index}} | {{item.name}} 
    <hr> 
    </item-template> </auratree> 
</body> 
</html> 

此代碼

tElement.find("script") 
    .html(tElement.find("script").html() 
    .replace("<item-placeholder></item-placeholder>",template.html())); 

在Chrome的工作,但不是在IE11工作。

通常element.replaceWith不工作,所以我試圖改變html ...但不成功。

請告訴我解決方案來克服這個問題。

這裏是plunker

回答

1

我不認爲你的方法與ng-template一樣按你期望的方式工作。即使您設法替換ng-template中的佔位符,但如果應用中有多個<auratree>元素,每個元素都有不同的項目模板,則所有模板都將具有相同的(最後編譯的)模板。

使用ng-include是一個聰明的技巧,但這個問題有點複雜。而不是依靠ng-include d模板,在每個級別包含相同的指令link-時間(這是什麼ng-include會做什麼),並使用transcludeitem-template

因爲每個子樹(其具有的值,並children)一個根元素之間的一些非對稱性(其僅具有項目的陣列),以及我添加另一指令來表示每個樹項:

的根指令只重複每個項目,並transcludes的item-template

app.directive("tree", function(){ 
    return { 
    restrict: "E", 
    scope: { 
     items: "=" 
    }, 
    transclude: true, 
    template: '<div ng-repeat="item in items">\ 
       <tree-item item="item"></tree-item>\ 
       </div>', 
    link: function(scope){ 
     scope.$level = -1; 
    } 
    }; 
}); 

treeItem指令transcludes從父item-template,並重復子項,如果有的話:

app.directive("treeItem", function($compile){ 
    return { 
    scope: { 
     item: "=" 
    }, 
    link: function(scope, element, attrs, ctrls, transclude){ 
     scope.$index = scope.$parent.$index; 
     scope.$level = scope.$parent.$level + 1; 

     transclude(scope, function(clone){ 
     element.append(clone.contents()); 
     var repeater = angular.element('<div ng-repeat="child in item.children">'); 
     var subtree = angular.element('<tree-item item="child">'); 

     element.append(repeater.append(subtree)); 

     $compile(repeater)(scope, null, { parentBoundTranscludeFn: transclude }); 
     }); 
    } 
    }; 
}); 

用法是:

<tree items="items"> 
    <item-template> 
    {{$level}}.{{$index}} | {{item.v}} 
    </item-template> 
</tree> 

Demo

0

最好把該模板的角度$templateCache裏面的角&運行階段,從指令中刪除該模板

運行阻滯

app.run(function($templateCache) { 

    $templateCache.put('auratree2', '<item-placeholder></item-placeholder>' + 
     '  <div ng-if="item.children">' + 
     '   <div ng-repeat="item in item.children" ng-include="' + 
     "'" + 'auratree2' + "'" + '">' + 
     '   <item-placeholder></item-placeholder></div>' + 
     '  </div>' 
    ); 
}); 

指令(模板功能)

template: function(element){  
    element.data("customListTemplate", element.find("item-template")); 
    var c= '<div ng-repeat="item in input" ng-include = "' + "'" +'auratree2' + "'"+ '"></div>'; 
    return c; 
}, 
+1

不工作.. BTW模板已被緩存..但我想更換使用replaceWith像** tElement佔位符的內容.find(「item-placeholder」)。replaceWith(template.contents()); ** –

-1

你的plunkr有JQuery,但是你的StackOverflow問題沒有,所以我假設你正在使用JQuery(你可能必須因爲JQLite的限制)。

在您的HTML文件中,修改JQuery和Angular的順序,使前者列在第一位。

<head> 
    <meta charset="utf-8" /> 
    <title>Aura Tree</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <script data-require="[email protected]*" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> 
    <script src="script.js"></script> 
    </head> 
+0

我想我可能在plunker中添加了jQuery錯誤,我沒有使用jQuery ... –