【问题标题】:binding variables to compiled elements in angular Js将变量绑定到角度 Js 中的已编译元素
【发布时间】:2014-05-29 07:17:27
【问题描述】:

我正在动态创建一个带角度的元素。当应用程序最初使用 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 放在单独的文件中。我做错了什么吗?

【问题讨论】:

  • 您使用.run() 函数来设置dom 有什么特别的原因吗?为什么不对动态元素使用指令?

标签: javascript html angularjs angularjs-scope


【解决方案1】:

忽略在.run 中进行 DOM 操作的缺点,您遇到的问题与指令的隔离范围有关。

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

为了实现这一点,我将摆脱 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

【讨论】:

  • 看起来是的,我应该在 AppCtrl 上生成元素,而不是运行函数。我仍在学习角度和最佳实践。话虽如此,我是否能够使用数据服务绑定活动变量,使用类似 app.factory("Data", function(){ var data = { active:false } return data; })
  • 当然,您可以将该服务注入您的控制器。然后你的控制器只需要将返回的值绑定到范围。
  • 感谢您的帮助我了解范围“=”以及它现在是如何工作的,您是否有一个示例说明如何做到这一点,在运行后将数据服务绑定到动态创建的元素$编译?
  • 它真的很接近我的想法, 通过执行类似 $scope.data = Data; 的操作然后将其传递给 ng-show
  • 非常感谢您的帮助,我从您的小提琴中学到了很多。
猜你喜欢
  • 2019-08-15
  • 1970-01-01
  • 2017-04-12
  • 2017-05-13
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
相关资源
最近更新 更多