AngularJs和两个控制器

时间:2016-02-25 23:25:22

标签: angularjs

我正在编写一个运行AngularJs&前端的Bootstrap - 并使用angularjs' $ http用于调用API ...我在一个应用程序中有两个控制器 - 第一个控制器显示该人的姓名,第二个控制器显示此人见过的表演列表......

<html lang="en" ng-app="myapp">
...
    <div class="panel-body" ng-controller="Ctrl">
        <div class="row">
            <div class="col-sm-3" style="height: 50px;">
                <div class="well well-sm">
                    First Name: 
                    <a href="#" editable-text="user.fname">{{ user.fname || "empty" }}</a>
                </div>
            </div>
            <div class="col-sm-3" style="height: 50px;">
                <div class="well well-sm">
                    Last Name: 
                    <a href="#" editable-text="user.lname">{{ user.lname || "empty" }}</a>
                </div>
            </div>
        </div>
    </div>
    <div class="list-group" ng-controller="Ctrl2">
        <div ng-repeat="obj in performances" >
            <div class="list-group-item">
                <h4 class="list-group-item-heading">
                <span class="badge">
                {{$index+1}}</span> {{ obj["Perf_name"] || "empty" }}</h4>
                <p class="list-group-item-text">
                        Date: {{ obj["Perf_dt"] || "empty" }}<br />
                        Theater: {{ obj["Theater"] || "empty" }}<br />
                </p>
            </div>
        </div>
    </div>
...
</html>

在JS文件中,我有以下代码

声明我的变量和模块

var app = angular.module("myapp", ["xeditable"]); 
var q = getUrlParameter("q"); // get the query param
var baseurl = "https://some.domain/service/getCRM";
var baseurl2 = "https://some.domain/service/getPerformances";

创建供两个控制器使用的服务

app.service('crmService', function () {
    this.id = 0; 
    this.getID = function () { return this.id };
    this.setID = function (newid) { this.id = newid; };
});

定义控制器#1

app.controller('Ctrl', function ($scope, $http, crmService) {
    $http({
        method: 'GET',
        url: baseurl,
        respondType: 'json',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        params: {
            phone_no: q
        }
    }).then(function successCallback(response) {
        $scope.user = {
            fname: response.data[0]["FirstName"],
            lname: response.data[0]["LastName"]
    }
        crmService.setID(response.data[0]["CRM_ID"]);

        console.log("*** OUTPUT LINE 1: " + crmService.getID());

    }, function errorCallback(response) {
        console.log("**ERROR");
        console.log(response);
    });
});

定义控制器#2

app.controller('Ctrl2', function ($scope, $http, crmService) {
    console.log("*** OUTPUT LINE 2: " + crmService.getID());

    var promise = $http.get(baseurl2 + "?crm_id=" + crmService.getID());
    promise.then(
        function (response) {
            $scope.performances = response.data;
    });
});

控制台输出

*** OUTPUT LINE 2: 0
*** OUTPUT LINE 1: 123456

问题:

  1. 为什么第二个控制器在第一个控制器之前输出,我认为是因为默认情况下AngularJs异步执行其代码,如果是这样的话,为什么&#34;承诺&#34;不行吗?
  2. 我需要做的是,我在第一个控制器块中进行GET调用并使用我的服务分配客户ID ...然后我继续使用我的服务中的第二个控制器块并使用客户ID(这是在第一个控制器块内设置的 - 获得客户的表现
  3. 所以我必须让第一个控制器工作正常,但第二个控制器一直认为客户ID 0 - 当它应该 123456

    我错过了什么?

    仅供参考:当我硬编码第二个控制器使用的ID时,我会得到实际的性能记录 - 所以我知道一旦我弄清楚如何在控制器之间共享值,一切都会正常工作

1 个答案:

答案 0 :(得分:1)

  

为什么第二个控制器在第一个

之前输出

因为第二个控制器在它实例化后立即记录该ID,而第一个控制器在它异步接收到对HTTP请求的响应后记录它。承诺确实有效,因为输出记录在控制台中。

  

我需要做的是,我在第一个控制器块中进行GET调用并使用我的服务分配客户ID ...然后我继续使用客户ID并从我的服务< / p>

你的工作比应有的更复杂:在这里使用单个控制器要容易得多,因为第二个控制器的模型取决于第一个控制器的作用。

你可以从第一个控制器广播一个事件来表示已经设置了ID,并在第二个控制器中监听事件以便在时间点获取数据。

app.controller('Ctrl', function ($scope, $http, $rootScope, crmService) {
    $http({
        ...
    }).then(function successCallback(response) {
        ...
        crmService.setID(response.data[0]["CRM_ID"]);
        console.log("*** OUTPUT LINE 1: " + crmService.getID());
        $rootScope.$broadcast('crmIdChanged');
    };
});

app.controller('Ctrl2', function ($scope, $http, crmService) {
    function getPerformances() {
        var id = crmService.getID();
        if (id != 0) {
            var promise = $http.get(baseurl2 + "?crm_id=" + crmService.getID());
            promise.then(
                function (response) {
                    $scope.performances = response.data;
            });
        }
    }

    getPerformances();
    $scope.$on('crmIdChanged', getPerformances);
});

你甚至可以从服务本身广播偶数。