2017-04-27 132 views
13

我試圖建立一個指令,將做到以下幾點:

  • 添加其他指令元素(ngSwipeRight例如)
  • 添加一些自定義行爲的新指示。

一個例子是:mySwipeBack會增加ngSwipeRight當用戶刷過的元素,我會做history.back()

我想是這樣的:

.directive('swipe', function($compile){ 
    return { 
    restrict: 'A', 
    compile: function(el){ 
     // I removed all the actual logic for demo purposes 
     // here I would add ng-swipe-right plus a handler 
     el.removeAttr('swipe'); 
     var fn = $compile(el); 
     return function (scope) { 
      fn(scope); 
     }; 
    } 
} 
}); 

但我遇到了一個問題與下面的標記:

<div ng-if='true'> 
    <h1 swipe>OUTSIDE 
    <div ng-if="true">INSIDE</div> 
    </h1> 
</div> 

「內部」的文字不會被渲染。 你可以看到在這個jsbin中的行爲:http://jsbin.com/tokofevuga/edit?html,js,output

如果我刪除第一個ng-if,它的工作原理如下。

有沒有人知道背後的原因是什麼 - 如果我能使它工作?

或者如果有人對如何實現我上面所述的另一個想法?

+0

以'NG-show'作品更換任何'NG-if's的。不知道爲什麼會發生。 – koox00

+0

是的,但我需要ng-if :) – sirrocco

+0

@sirrocco參考指令的'compile'函數中的代碼:爲什麼您要手動編譯元素?如果刪除編譯函數中的最後三行只有'el.removeAttr('swipe');'它按預期工作 –

回答

8
return function (scope) { 
     $compile(el)(scope); 
    }; 

工作對我來說... 而且一點是,在你的代碼 - 你馬上編譯元素指令編譯,而在這裏的功能是由編譯返回,將somewhen後執行。

0

考慮一下。 ngIf刪除整個元素並將其替換爲註釋。然後觀察表達式。隨後的更改觸發DOM到REMOVED之間的元素。

現在的問題是,你已經把塊放在編譯階段。整個ng-if的代碼被替換爲單個註釋。

關於解決方案,可以有很多。這一切都取決於結構和需求,如果你的應用程序很好。

我提出兩種:

1)從 '編譯' 到 '鏈接' 相移的邏輯。

link: function(el){ 
    el.removeAttr('swipe'); 
    var fn = $compile(el); 
    return function (scope) { 
     fn(scope); 
    }; 
}, 

2)您將需要使用transclusion。

app.directive('swipe', function($compile){ 
return { 
    restrict: 'A', 
    compile: function(el){ 
    el.removeAttr('swipe'); 
    var fn = $compile(el); 
    return function (scope) { 
     fn(scope); 
     }; 
    }, 
    transclude: true, 
    template: "<div ng-transclude></div>" 
} 
}); 

你的樣品以下叉可能會引導你:

http://jsbin.com/zecujonoqi/1/edit?html,js,output

http://jsbin.com/mubodevofa/1/edit?html,js,output

希望它能幫助。

1

由於ng-if創建了自己的scope,我認爲你只是過早編譯元素。

在下面的代碼片段中,我將compile part移動到link,並將該元素與指令本身的當前作用域綁定。

var app = angular.module('jsbin', []); 
 

 
app.controller('DemoCtrl', function() { 
 

 
}); 
 

 
app.directive('swipe', function($compile) { 
 
    return { 
 
    restrict: 'A', 
 
    link: function($scope, el) { 
 
     el.removeAttr('swipe'); 
 
     $compile(el)($scope); 
 
    } 
 
    } 
 
});
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <title>Angular JS</title> 
 
</head> 
 

 
<body ng-app="jsbin"> 
 
    <div ng-controller="DemoCtrl"> 
 
    <div ng-if='true'> 
 
     <h1 swipe>OUTSIDE 
 
     <div ng-if="true">INSIDE</div> 
 
     </h1> 
 
    </div> 
 
    </div> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.js"></script> 
 
</body> 
 

 
</html>