控制器功能中的角度设置 $scope.value 不起作用 [英] angular set $scope.value in controller function is not working

查看:34
本文介绍了控制器功能中的角度设置 $scope.value 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在由指令创建的控制器函数中设置一个角度变量值.不知何故,由于某些未知原因,它无法正常工作.该值在独立设置时显示,但在我尝试在控制器函数中分配值时不起作用.

我的代码如下,

<头><meta charset="UTF-8"/><script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script><script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script><身体><div ng-app="mainApp"><div ng-controller="MyController"><div id="Details" class="Details">{{Details}}</div></br><div id="Test" class="Test"><collection collection='testdata'></collection>

<脚本>var mainApp = angular.module("mainApp", [])mainApp.directive('collection', function () {返回 {限制:E",替换:真的,范围:{collection: '=', showFn : '&'},模板:<ul><member ng-repeat='member in collection' member='member'></member></ul>"}})mainApp.directive('member', function ($compile) {var NewChild = "<li><span ng-click=ShowDetailsFunc()>{{member.TagName}}</span></li>";返回 {限制:E",替换:真的,范围:{member: '=', ShowHideCtrlFunc : '&', ShowDetailsCtrlFunc : '&'},模板:NewChild,控制器:'我的控制器',链接:函数(范围、元素、属性){var collectionSt = '<collection collection="member.children"></collection>';如果(angular.isArray(scope.member.children)){$compile(collectionSt)(范围,功能(克隆,范围){element.attr('xml-path', scope.member.TagPath);element.append(克隆);});scope.ShowDetailsFunc = function() {scope.ShowDetailsCtrlFunc(element,event);}}}}})mainApp.controller('MyController', function ($scope) {$scope.testdata = [{"TagName":"MyRootNode","TagPath":">MyRootNode","children":[{"TagName":"LandXML","TagPath":">MyRootNode>ChildItems>LandXML","children":[{"TagName":"Units","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Units","children":[{"TagName":"Imperial","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[1]>Imperial","children":[]},{"TagName":"Project","TagPath":">;MyRootNode>ChildItems>ChildItems[1]>Project","children":[]},{"TagName":"Application","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Application","children":[{"TagName":"Author","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[2]>Author","children":[]},{"TagName":"Alignments","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Alignments","children":[]},{"TagName":"Roadways","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Roadways","children":[{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[1]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[2]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[3]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[4]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[5]","children":[]}]}]}]}]},{"TagName":"Surfaces","TagPath":">MyRootNode>ChildItems>Surfaces","children":[{"TagName":"Surface1","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface1","children":[]},{"TagName":"Surface2","TagPath":">;MyRootNode>ChildItems>ChildItems[2]>Surface2","children":[]}]}]}]$scope.Details = "默认值"$scope.ShowDetailsCtrlFunc = 函数(元素,事件){console.log("在函数 ShowDetailsCtrlFunc");var myxmlpath = $(element).attr("xml-path")$scope.Details = getObjects($scope.testdata, 'TagPath', myxmlpath)[0].TagName;console.log($scope.Details)//event.stopImmediatePropagation();};});函数 getObjects(obj, key, val) {var 对象 = [];for (var i in obj) {if (!obj.hasOwnProperty(i)) 继续;if (typeof obj[i] == 'object') {objects = objects.concat(getObjects(obj[i], key, val));} else if (i == key && obj[key] == val) {对象.推(对象);}}返回对象;}</html>

请帮助我了解我在哪里犯了错误以及如何纠正.

请帮忙.非常感谢.

解决方案

问题在于,当您以这种循环方式创建指令时,您正在嵌套 MyController-controller.结果是 $scope.Details 被设置在特定的嵌套作用域上,而不是在视图中呈现值的作用域.

您可以通过 $emit 将新值发送到上游并最终达到呈现范围值的更改来解决此问题.

这是一个例子

var mainApp = angular.module("mainApp", [])mainApp.directive('collection', function () {返回 {限制:E",替换:真的,范围:{collection: '=', showFn : '&'},模板:<ul><member ng-repeat='member in collection' member='member'></member></ul>"}})mainApp.directive('member', function ($compile) {var NewChild = "<li><span ng-click=ShowDetailsFunc()>{{member.TagName}}</span></li>";返回 {限制:E",替换:真的,范围:{member: '=', ShowHideCtrlFunc : '&', ShowDetailsCtrlFunc : '&'},模板:NewChild,控制器:'我的控制器',链接:函数(范围、元素、属性){var collectionSt = '<collection collection="member.children"></collection>';如果(angular.isArray(scope.member.children)){$compile(collectionSt)(范围,功能(克隆,范围){element.attr('xml-path', scope.member.TagPath);element.append(克隆);});scope.ShowDetailsFunc = function() {scope.ShowDetailsCtrlFunc(element);}}}}})mainApp.controller('MyController', function ($scope) {$scope.testdata = [{"TagName":"MyRootNode","TagPath":">MyRootNode","children":[{"TagName":"LandXML","TagPath":">MyRootNode>ChildItems>LandXML","children":[{"TagName":"Units","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Units","children":[{"TagName":"Imperial","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[1]>Imperial","children":[]},{"TagName":"Project","TagPath":">;MyRootNode>ChildItems>ChildItems[1]>Project","children":[]},{"TagName":"Application","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Application","children":[{"TagName":"Author","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[2]>Author","children":[]},{"TagName":"Alignments","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Alignments","children":[]},{"TagName":"Roadways","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Roadways","children":[{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[1]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[2]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[3]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[4]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[5]","children":[]}]}]}]}]},{"TagName":"Surfaces","TagPath":">MyRootNode>ChildItems>Surfaces","children":[{"TagName":"Surface1","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface1","children":[]},{"TagName":"Surface2","TagPath":">;MyRootNode>ChildItems>ChildItems[2]>Surface2","children":[]}]}]}]$scope.Details = "默认值";$scope.ShowDetailsCtrlFunc = 函数(元素){console.log("在函数 ShowDetailsCtrlFunc");var myxmlpath = angular.element(element).attr("xml-path")var detail = getObjects($scope.testdata, 'TagPath', myxmlpath)[0].TagName;控制台日志(详细信息);$scope.$emit('detailSelected',detail);//event.stopImmediatePropagation();};$scope.$on('detailSelected',function($event, message){$scope.Details = 消息;});});函数 getObjects(obj, key, val) {var 对象 = [];for (var i in obj) {if (!obj.hasOwnProperty(i)) 继续;if (typeof obj[i] == 'object') {objects = objects.concat(getObjects(obj[i], key, val));} else if (i == key && obj[key] == val) {对象.推(对象);}}返回对象;}

<头><meta charset="UTF-8"/><script data-require="angularjs@1.6.4" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></脚本><身体><div ng-app="mainApp"><div ng-controller="MyController"><div id="Details" class="Details">{{Details}}</div></br><div id="Test" class="Test"><collection collection='testdata'></collection>

</html>

I am trying to set a angular variable value in controller function which is created by a directive. Somehow it is not working for some unknown reasons. The value is displayed when set independently but doesn't work when i try to assign value in a controller function.

My code is as below,

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>

</head>
<body>
    <div ng-app="mainApp">
        <div ng-controller="MyController">
            <div id="Details" class="Details">{{Details}}</div></br>
             <div id="Test" class="Test">
             <collection collection='testdata'></collection>             
             </div>          
        </div>              
    </div>
</body>
<script>    
var mainApp = angular.module("mainApp", [])

mainApp.directive('collection', function () {
    return {
        restrict: "E",
        replace: true,
        scope: {collection: '=', showFn : '&'},
        template: "<ul><member ng-repeat='member in collection' member='member'></member></ul>"         
    }
})

mainApp.directive('member', function ($compile) {
    var NewChild = "<li><span ng-click=ShowDetailsFunc()>{{member.TagName}}</span></li>";

    return {
        restrict: "E",
        replace: true,
        scope: {member: '=', ShowHideCtrlFunc : '&', ShowDetailsCtrlFunc : '&'},
        template: NewChild,
        controller: 'MyController',
        link: function (scope, element, attrs) {            
            var collectionSt = '<collection collection="member.children"></collection>';
            if (angular.isArray(scope.member.children)) {               
                    $compile(collectionSt)(scope, function(cloned, scope)   {                                           
                        element.attr('xml-path', scope.member.TagPath);
                        element.append(cloned);                         
                     });                      
                    scope.ShowDetailsFunc = function() {
                        scope.ShowDetailsCtrlFunc(element,event);                     
                    }

            }
        }   

    }
})

mainApp.controller('MyController', function ($scope) {
    $scope.testdata = [{"TagName":"MyRootNode","TagPath":">MyRootNode","children":[{"TagName":"LandXML","TagPath":">MyRootNode>ChildItems>LandXML","children":[{"TagName":"Units","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Units","children":[{"TagName":"Imperial","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[1]>Imperial","children":[]},{"TagName":"Project","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Project","children":[]},{"TagName":"Application","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Application","children":[{"TagName":"Author","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[2]>Author","children":[]},{"TagName":"Alignments","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Alignments","children":[]},{"TagName":"Roadways","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Roadways","children":[{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[1]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[2]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[3]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[4]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[5]","children":[]}]}]}]}]},{"TagName":"Surfaces","TagPath":">MyRootNode>ChildItems>Surfaces","children":[{"TagName":"Surface1","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface1","children":[]},{"TagName":"Surface2","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface2","children":[]}]}]}]

    $scope.Details = "defalut value"
    $scope.ShowDetailsCtrlFunc = function(element,event) {
            console.log("in function ShowDetailsCtrlFunc");                     
            var myxmlpath = $(element).attr("xml-path")
            $scope.Details = getObjects($scope.testdata, 'TagPath', myxmlpath)[0].TagName; 
            console.log($scope.Details)                         
            //event.stopImmediatePropagation();
      };    
});
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}   
</script>   
</html>

Please help me to understand where i am making mistake and how it can be rectified.

Please help. Many thanks in advance.

解决方案

The problem is that you are nesting MyController-controller when you create the directives in this circular way. The result is that the $scope.Details gets set on the specific nested scope instead of the one which is presenting the value in the view.

You can solve this by $emit the change which will send the new value upstream and finally reach the presenting scope value.

Here's an example

var mainApp = angular.module("mainApp", [])

mainApp.directive('collection', function () {
    return {
        restrict: "E",
        replace: true,
        scope: {collection: '=', showFn : '&'},
        template: "<ul><member ng-repeat='member in collection' member='member'></member></ul>"         
    }
})

mainApp.directive('member', function ($compile) {
    var NewChild = "<li><span ng-click=ShowDetailsFunc()>{{member.TagName}}</span></li>";

    return {
        restrict: "E",
        replace: true,
        scope: {member: '=', ShowHideCtrlFunc : '&', ShowDetailsCtrlFunc : '&'},
        template: NewChild,
        controller: 'MyController',
        link: function (scope, element, attrs) {            
            var collectionSt = '<collection collection="member.children"></collection>';
            if (angular.isArray(scope.member.children)) {               
                    $compile(collectionSt)(scope, function(cloned, scope)   {                                           
                        element.attr('xml-path', scope.member.TagPath);
                        element.append(cloned);                         
                     });                      
                    scope.ShowDetailsFunc = function() {
                        scope.ShowDetailsCtrlFunc(element);                     
                    }

            }
        }   

    }
})

mainApp.controller('MyController', function ($scope) {
    $scope.testdata = [{"TagName":"MyRootNode","TagPath":">MyRootNode","children":[{"TagName":"LandXML","TagPath":">MyRootNode>ChildItems>LandXML","children":[{"TagName":"Units","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Units","children":[{"TagName":"Imperial","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[1]>Imperial","children":[]},{"TagName":"Project","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Project","children":[]},{"TagName":"Application","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Application","children":[{"TagName":"Author","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[2]>Author","children":[]},{"TagName":"Alignments","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Alignments","children":[]},{"TagName":"Roadways","TagPath":">MyRootNode>ChildItems>ChildItems[1]>Roadways","children":[{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[1]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[2]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[3]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[4]","children":[]},{"TagName":"Roadway","TagPath":">MyRootNode>ChildItems>ChildItems[1]>ChildItems[3]>Roadway[5]","children":[]}]}]}]}]},{"TagName":"Surfaces","TagPath":">MyRootNode>ChildItems>Surfaces","children":[{"TagName":"Surface1","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface1","children":[]},{"TagName":"Surface2","TagPath":">MyRootNode>ChildItems>ChildItems[2]>Surface2","children":[]}]}]}]

    $scope.Details = "defalut value";
    $scope.ShowDetailsCtrlFunc = function(element) {
            console.log("in function ShowDetailsCtrlFunc");                     
            var myxmlpath = angular.element(element).attr("xml-path")
            var detail = getObjects($scope.testdata, 'TagPath', myxmlpath)[0].TagName; 
            console.log(detail);
            $scope.$emit('detailSelected',detail);
            //event.stopImmediatePropagation();
      };
      $scope.$on('detailSelected',function($event, message){
      $scope.Details = message;
    });
});
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<script data-require="angularjs@1.6.4" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>

</head>
<body>
    <div ng-app="mainApp">
        <div ng-controller="MyController">
            <div id="Details" class="Details">{{Details}}</div></br>
             <div id="Test" class="Test">
             <collection collection='testdata'></collection>             
             </div>          
        </div>              
    </div>
</body>
  
</html>

这篇关于控制器功能中的角度设置 $scope.value 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆