获取控制器中$scope的指令值

Get value from directive to $scope in controller

本文关键字:指令 scope 控制器 获取      更新时间:2023-09-26

在我的指令中,我从后端获得了一些数据,如下所示:

var monster_info = angular.element(this).find("img").attr("title");
                    $http.get("lib/terrain.php", {params: { monster_data:monster_info}}).success(function(data) {
                            console.log(data);
                    });

我希望这些数据出现在我的网站上,所以我尝试在我的控制器中声明一个这样的变量:$scope.fish=[];

然后,我只在指令中分配这样的数据值:$scope.fish=data;

但是什么都没有打印出来。控制器和指令之间的通信是如何工作的?我应该如何共享此类数据?

这是我的全部指令:

angular.module('gameApp_directives').
  directive('mapActivity', function($http) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch('tabledata', function() {
             angular.element('.click#1').addClass('dotted').html($("<img src='images/dot.png'>"));          
                var j = null;
                for(var i = 1; i <= 4; i++)
                {
                    $.ajax({
                        type: 'GET',
                        url: 'lib/terrain.php',
                        dataType: 'html',
                        data: {i: i},
                        success: function(data) {
                            var randomRuta = Math.floor((Math.random() * 100) + 1);
                            angular.element('.click#'+randomRuta).addClass('monster').html($("<img src='images/blackdot.png' title='"+data+"'>"));                  
                        },
                        error: function(xhr, ajaxOptions, thrownError) { alert(thrownError); }
                    });
                    j=i;
                }  
                angular.element('.click').click(function() {
                    if(angular.element(this).hasClass('monster'))
                    {
                        var monster_info = angular.element(this).find("img").attr("title");
                        $http.get("lib/terrain.php", {params: { monster_data:monster_info}}).success(function(data) {
                                console.log(data);
                        });

                        /*if(confirm('Vill du anfalla monster?'))
                        {
                            alert("Du vann");
                            angular.element('.click.monster'+j).empty();
                            angular.element('.click.monster').removeClass('monster'+j);
                            angular.element('.click.dotted').empty();
                            angular.element('.click.dotted').removeClass('dotted');
                            angular.element(this).addClass('dotted');
                            angular.element('.click.dotted').html($('<img src="images/dot.png">'));
                        }*/
                    }
                    else
                    {
                        angular.element('.click.dotted').empty();
                        angular.element('.click.dotted').removeClass('dotted');
                        if(!angular.element(this).hasClass('dotted'))
                        {
                            angular.element(this).addClass('dotted');
                            angular.element(this).html($('<img src="images/dot.png">'));
                        }
                    }
                });
            });                     
        }
    };
});

这是我的控制器:

angular.module('gameApp_controllers')
    .controller('gameCtrl', ['$scope', '$http', '$location', '$sce', '$rootScope', 'link', function($scope, $http, $location, $sce, $rootScope, link) {
        $scope.resultLoaded = false;
        $scope.getMonsters = "1";
        var tabledata = ""; //Variable to store pattern for html table
        $http.post("lib/action.php", {monsters: $scope.getMonsters}).success(function(data) {   
            //tabledata = data; //Assign the pattern
            $scope.result = makeTableFrom(data); //Call the function to build the table based on the pattern
            $scope.resultLoaded = true;
        }).error(function(data) { console.log("error"); });
        $scope.fish = [];
        $scope.safeHtml = function() {
            return $sce.trustAsHtml($scope.result);
        };

        if(link.user) {
            /*$scope.message = "fisk";
            console.log(link.user);*/
        } else {
        /*$scope.message = "Ledsen fisk";
        console.log("Är inte satt");*/
        }
}]).controller('firstPageCtrl', ['$scope','$http','$location','$sce','$rootScope','link', function($scope, $http, $location, $sce, $rootScope, link) {
        $scope.doLogin = function() {
        $http.post("lib/action.php", {username: $scope.username, password: $scope.password}).success(function(data) {
            if(data) {
                link.user = data;
                console.log(link.user);
                $location.path("/game");
            }
        }).error(function(data) {
            console.log(data);
        });
    };
}]);

有谁能帮我吗?

这是我的HTML

<div id="layout_game">
<div ng-controller="gameCtrl">
<div ng-if='resultLoaded' id="rightcontent_game">
    <table ng-bind-html="safeHtml()" map-Activity>
    </table>
</div>
<div id="leftcontent_game">
    <div id="leftcontent_top">
        <ul>
            <li><a href="#">Vildmarken</a></li> <li> | </li> <li><a href="#">Marknaden</a></li> <li> | </li> <li><a href="#">Värdshuset</a></li>
        </ul>
    </div>
    {{fish}}
</div>
</div>
</div>

我只会从如下指令中广播一个事件:

  $rootScope.$broadcast('fishChange', fishValue);

然后在控制器中侦听该事件:

  $scope.$on('fishChange', function(event, fishValue) {
   // Do whatever you want here
});

指令与其父控制器之间的通信可以通过几种不同的方式进行,具体取决于如何在指令定义对象中定义scope属性。

默认值是scope: false,这是您在上面的mapActivity指令示例中隐式使用的,因为您没有指定一个。(对于其他模式,请参阅$compile上的文档,在"范围"设置下)

这意味着没有创建新的作用域-指令将通过作为链接函数的第一个参数传递的scope参数直接访问包含控制器的$scope。

您的代码可能不起作用,原因很简单,您在指令中写了$scope.fish = data,而不是scope.fish = data(没有美元符号)。实际上,查看您发布的指令代码,您不会尝试在任何位置分配给fish属性。也许你只是在例子中忽略了它?

re:使用'$rootScope$广播()'

我个人建议不要使用lulu88建议的$rootScope.broadcast()方法。我将保留在$rootScope上的广播,仅用于在两个组件之间没有简单、直接的通信方式的情况。在这种情况下,正如我所解释的,有一个非常简单的方法。

来自Angular文档

$broadcast(名称,args)

向下向所有子作用域(及其子作用域)分派事件名称,通知已注册的$rootScope.Scope侦听器。

事件生命周期从调用$broadcast的范围开始。所有侦听此作用域上的name事件的侦听器都会收到通知。然后,该事件传播到当前作用域的所有直接和间接作用域,并在此过程中调用所有注册的侦听器。无法取消活动。

因此,如果您在$rootScope上调用$broadcast(),您将把事件传播到应用程序中的每个作用域。除了全局应用程序范围的事件(典型的事件是用户登录或注销)之外,这对任何事情都是不必要的。

您可能知道"input"或"select"HTML组件可以使用ng模型向控制器报告其状态。事实上,我们也可以使我们自己的指令支持相同的功能。

该过程可以被消化为:

  1. 将"require:'ngModel'"添加到指令的js中,使ng模型在模板html中可用
  2. 使用ngModelCtrl$formatters方法将模型值转换为视图值
  3. 使用ngModelCtrl$render方法更新UI以反映视图值
  4. 使用ngModelCtrl$parsers方法将视图值转换为模型值
  5. 使用ngModelCtrl$setViewValue方法,以便在UI更改时更新视图值

全圆形的可视化

<realModel>→ngModelCtrl$格式化程序(realModel)→ $viewModel↓↑                                                  $render()↓↑UI已更改↓ngModelCtrl$解析器(newViewModel)←    $setViewValue(newViewModel)

完整版教程