跨视图控制器传输值不工作

Transporting value across view controllers not working

本文关键字:工作 传输 视图 控制器      更新时间:2023-09-26

在angular js应用程序中,我有一个在main.html中定义为可点击项的表列。单击后,它将转到一个新的客户页面,并携带列单元格的值作为客户名称。我在main.js中为app模块定义了相应的服务。

客户页面视图接收所选/单击客户的时间序列活动数据,并应该为客户显示各种图表和表格。视图和它的控制器代码也是附加的。还附加了REST API服务。

我期望当客户在表列单元格上单击时,控件应该转到main.js中相应服务下的setClientFromSelection() -在那里我有console.log来打印客户端名称-它不会去那里!

不知道我犯了什么错误!如有任何指示,我将不胜感激。

main.html(相关代码):

<tr ng-repeat="data in clientdata track by data.attributes.client" ng-if="data.attributes.Status == statusColor">
<td><a ng-href="#customer" ng-click="setClientFromSelection(data.attributes.client)">{{data.attributes.client.split(".")[0]}}</a></td></tr>
main.js(相关代码):
'use strict';
angular.module('c3App')
    .controller('MainCtrl', ['$scope', 'ClientPerf', 'colorTransportService',
        function ($scope, ClientPerf, colorTransportService) {
            ClientPerf.get()
                .success(function(data) {
                    if (angular.isUndefined($scope.statusColor))  { $scope.statusColor = 'RED'; };
                    $scope.clientdata = data.payload.array;
                });
            $scope.$on('healthStatusClicked', function(e, color) {
                $scope.statusColor = angular.uppercase(color);
            });
    }])
    .service('clientTransportService', ['$rootScope', function($rootScope) {
        var client = '';
        var setClientFromSelection = function(clientName) {
            console.log("clientName: ", clientName);
            client = clientName;
            console.log("client: ", client);
            $rootScope.$broadcast('clientSelected', client);
        }
        var getSelectedClient = function() { return client; }
        return { 
            setClientFromSelection: setClientFromSelection, 
            getSelectedClient: getSelectedClient 
        };
    }])

clientDetails.html视图:

<div class="col-lg-6 text-center">
    <div class="panel panel-default" ng-style="{'width': '100%'}">
        <div class="panel-heading">
            <h3 class="panel-title">Usage<linechart data="dailyUsageData" options="dailyUsageOptions" mode=""></linechart></h3>
        </div>
        <div id="customer_activities_graph" ng-style="{'width': '97%'}"></div>
    </div>      
    <div class=" panel panel-default" ng-style="{'width': '100%'}">
        <div class="panel-heading">
            <h3 class="panel-title">{{client}} Timeline</h3>
        </div>
        <div id="container5" ng-style="{'width': '95%', 'margin-left': '2%'}"></div>
    </div>
</div>

customer.js控制器相关代码:

'use strict';
angular.module('c3App')
    .controller('CustomerCtrl', ['$scope', 'DailyUsage4Client', 'clientTransportService',
        function ($scope, DailyUsage4Client, clientTransportService) {
            $scope.dailyUsageData = [];
            $scope.dailyUsageOptions = {
                axes: {x: {type: "date", key: "x"}, y: {type: "linear"}},
                series: [
                    {
                      y: "value",
                      label: "Activity Count",
                      color: "#ff7f0e",
                      type: "column",
                      axis: "y"
                    }],
                tooltip: {
                    mode: "scrubber",
                    formatter: function (x, y, series) {
                          return moment(x).fromNow() + ' : ' + y;
                        }
                    },
                stacks: [],
                lineMode: "linear",
                tension: 0.7,
                drawLegend: true,
                drawDots: true,
                columnsHGap: 5
            };
            DailyUsage4Client.get()
                .success(function (data) {
                    if (angular.isUndefined($scope.client)) { $scope.client = 'servicemax.com'; };
                    var dailyUsage = data.payload.array;
                    for(var k = 0; k < dailyUsage.length; k++) {
                        $scope.dailyUsageData.push({
                            date: new Date(dailyUsage[k].attributes.dt.toString().replace(/('d{4})('d{2})('d{2})/, "$2/$3/$1")),
                            value: dailyUsage[k].attributes.activities
                        });
                    };
                });
            $scope.$on('clientSelected', function(e, client) {
                $scope.client = client.split(".")[0];
            });
    }]);
为了完整起见,我将Rest调用定义如下:
angular.module('ClientServices', ['ngResource'])
    .config(function ($httpProvider) {
        $httpProvider.defaults.headers.post['Content-Type'] = 'application/json';
        $httpProvider.defaults.cache = false;
    })
    .factory("DailyUsage4Client", function($http, $rootScope) {
        return {
            get: function() { return $http.get('http://c3.captora.com/c3rests/c3/usageByDay/{{client}}'); }
        }
    });

clientTransportService是一个工厂(返回一个对象),但被用作服务。尝试将其更改为工厂…

.factory('clientTransportService', ['$rootScope', function($rootScope) {
    // ...
    return { 
        setClientFromSelection: setClientFromSelection, 
        getSelectedClient: getSelectedClient 
    };
}])

或者将其修改为服务…

.service('clientTransportService', ['$rootScope', function($rootScope) {
    var client = '';
    this.setClientFromSelection = function(clientName) {
        console.log("clientName: ", clientName);
        client = clientName;
        console.log("client: ", client);
        $rootScope.$broadcast('clientSelected', client);
    }
    this.getSelectedClient = function() { return client; }
}])

控制器还需要将setClientFromSelection()添加到作用域…

$scope.setClientFromSelection = clientTransportService.setClientFromSelection;

clientTransportService更改为工厂,因为它正在返回一个对象。或者更改您的服务定义,使其成为Anthony Chu回答的服务。

这是因为当你注入一个服务时,你会得到一个在服务定义中传递的函数的实例。

当你注入一个工厂时,你将通过调用你在工厂定义中传递的函数返回一个值。

查看服务、工厂和供应商的完整答案

你没有利用好一个合适的路线计划,这会让你的生活变得不必要的艰难。考虑在你的app.js文件中(或者在你配置主应用模块的任何地方)创建如下路由:

$routeProvider.when('/customers/:customer_id', {
        templateUrl : '/views/customer.html',
        controller : 'CustomerCtrl'
});

因此,您可以简单地链接到正确的客户id。

在你的控制器中,你可以从$routeParams中检索id,如下所示:

angular.module('yourApp').controller('OrganisationCtrl', function ($scope, $log, $window, $routeParams, $filter, kometContent, kometSystem, $location, $sce, $alert) {
    ($scope.getCustomer = function(id) {
        kometContent.customer(id).then(function (response) {
            $scope.customer = response;
        }, function (response) {
            $scope.$emit(kometSystem.error, 'Server error ' + response.status);
        });
    })($routeParams.customer_id);
});

请注意,我们正在通过$routeParams获得传递给自运行匿名方法的id。这就是我们所说的约定高于代码的意思。这样不是容易多了吗?现在,我们可以简单地链接到'/customers/:customer_id'(例如,'/customers/17'),而无需任何特殊处理。