奇怪的ngIf + $编译行为

时间:2017-04-27 03:40:25

标签: angularjs angularjs-directive

我正在尝试构建一个执行以下操作的指令:

  • 向元素添加另一个指令(例如ngSwipeRight)
  • 向新指令添加一些自定义行为。

一个示例是:payload = {"user_id": 1, "query_type": "GEOSPLIT", "address": u"广东省深圳市宝安".encode('gbk'), "ret_splitinfo": 1} r = requests.get("http://10.202.15.197:20176", payload) print r.text 会添加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);
        };
   }
 }
});

" INSIDE"文字没有被渲染。 您可以在此jsbin中查看行为:http://jsbin.com/tokofevuga/edit?html,js,output

如果我删除了第一个ng-if,它就会按预期工作。

有谁知道这背后的原因是什么 - 如果我能使它发挥作用?

或者,如果有人对如何实现上述描述有另一个想法?

3 个答案:

答案 0 :(得分:8)

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

为我工作...... 关键是在你的代码中 - 你在编译指令中立即编译元素,而这里函数从编译返回,稍后将执行。

答案 1 :(得分: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>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

考虑一下。 ngIf删除整个元素并用注释替换它。然后观察表达式。随后的更改会从DOM到REMOVED之间触发元素。

现在问题是,您已将块放在编译阶段。整个ng-if的代码被单个注释替换。

关于解决方案,可以有很多。这一切都取决于你的应用程序的结构和需求。

我建议两个:

1)将逻辑从“编译”移动到“链接”阶段。

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

2)您需要使用翻译。

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

希望它有所帮助。