将变量绑定到角度Js中的已编译元素

时间:2014-05-28 21:58:49

标签: javascript html5 angularjs angularjs-scope

我正在动态创建一个带角度的元素。当应用程序最初使用app.run()运行时,元素被创建并且我编译元素,在编译元素后我添加了一个ng-show =“active”,这样我就可以切换元素的可见性并可能在以后设置转换动画使用该指令。唯一的问题是编译元素只有在看起来变量active时才会绑定。一旦设置为true,它就不会再次隐藏。我是否需要使用摘要或其他方法来使绑定正常工作?

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="lib/angular/angular.min.js"></script>
    <link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
    <style>
        .message-app { width:100px; height:30px; background-color:#005cab; color:white; text-align:center; line-height:30px; margin-bottom:5px; }
        .app-console { width:300px; height:30px; border:1px solid red; }
    </style>
 </head>
<body ng-controller="AppCtrl">

    <div class="message-app" val=''>click</div>
    <div class="message-app" val='true'>click</div>

</body>
</html>
<script>
    var app = angular.module("messageApp", []);

    app.run(function($rootScope){

        $rootScope.message = angular.element("<div class='app-console' ng-show='active'></div>");


        angular.element(document.body).append($rootScope.message);

    })

    function AppCtrl($scope, $compile, $rootScope){

        $scope.active = false;


        $compile($rootScope.message)($scope);

        $scope.setActive = function(val){

            $scope.active = val;
            $scope.$apply();
        }

    }

    app.directive("messageApp", function(){

        return {

            restrict:"C",
            controller:"AppCtrl",
            scope:{

                val:"@"

            },
            link:function(scope, element, attr){

                element.bind("click", function(){

                    scope.setActive(Boolean(scope.val));

                })

            }

        }

    })

    angular.element(document).ready(function(){

        angular.bootstrap(document.querySelector("html"), ["messageApp"])

    })

</script>

为了简单起见,我没有把js放在一个单独的文件中。我有什么问题吗?

1 个答案:

答案 0 :(得分:1)

对在.run中执行DOM操作的缺点进行了说明,您所遇到的问题与您的指令的隔离范围有关。

当您从指令调用setActive()时,setActive()内的所有范围引用都是调用对象的范围(这是指令的隔离范围)。因此,您当前正在每个指令的隔离范围上操作属性active。但是,您想要更改active范围内的appCtrl

为了实现这一点,我将摆脱setActive(),并在你的指令中完成这3步骤:

1)将active添加到指令的范围:

scope:{
  val:"@",
  isactive: "="
},

2)将active传递给你的指令:

<div class="message-app" val='' isactive="active">click</div>
<div class="message-app" val='true' isactive="active">click</div>

3)直接在点击处理程序中更改active

element.bind("click", function(){
  scope.$apply(function() {
     scope.isactive =Boolean(scope.val);
  });
});

现在您不必担心让您的指令与您的控制器对话,或者您正在使用哪个范围。而且你的指令有一个清晰的界面。

这是working fiddle