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

时间:2014-08-26 11:47:57

标签: javascript angularjs angularjs-directive

在我的指令中,我从后端获取了一些数据:

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>

3 个答案:

答案 0 :(得分:1)

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

默认值为scope: false,这是您在上面的mapActivity指令示例中隐式使用的,因为您没有指定。{1}}。 (对于其他模式,请参阅“范围”设置下的docs on $compile

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

您的代码可能无法正常工作,原因很简单,您在指令中编写了$scope.fish = data,而不是scope.fish = data(没有美元符号)。实际上,查看您发布的指令代码,您不会尝试在任何地方分配fish属性。也许你只是在示例中省略了它?

re:使用'$ rootScope。$ broadcast()'

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

来自Angular docs

  
    
      

$ broadcast(name,args);

             

将事件名称向下调度到所有子范围(及其子级),通知已注册的$ rootScope.Scope侦听器。

             

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

    
  

因此,如果您在$ rootScope上调用$ broadcast(),您将把该事件传播到应用中的每个范围。除了全局应用程序范围的事件之外,这是不必要的 - 通常是用户登录或注销的事件。

答案 1 :(得分:0)

我会直接从指令广播一个事件:

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

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

  $scope.$on('fishChange', function(event, fishValue) {

   // Do whatever you want here

});

答案 2 :(得分:0)

您可能知道“输入”或“选择”HTML组件可以使用ng-model向控制器报告其状态。事实上,我们也可以使自己的指令支持相同的功能。

该过程可以被消化为:

  1. 将“require:'ngModel'”添加到指令的js中,让ng-model在模板html中可用。
  2. 使用ngModelCtrl。$ formatters方法将模型值转换为视图值。
  3. 使用ngModelCtrl。$ render方法更新UI以反映视图值。
  4. 使用ngModelCtrl。$ parsers方法将视图值转换为模型值。
  5. 使用ngModelCtrl。$ setViewValue方法在UI更改时更新视图值。
  6. 可视化整个圆圈

    <realModel> → ngModelCtrl.$formatters(realModel) → $viewModel
                                                           ↓
    ↑                                                  $render()
                                                           ↓
    ↑                                                  UI changed
                                                           ↓
    ngModelCtrl.$parsers(newViewModel)    ←    $setViewValue(newViewModel)
    

    The full version tutorial