$scope.$watch 似乎没有观察工厂变量

$scope.$watch does not seem to watch factory variable

我是 angularjs 的初学者。在我的 NFC 项目中,我希望能够根据不断变化的 patientId.

从服务器获取数据

但是,我无法看到我的 $watch 正确执行,即使每次扫描新的 NFC 标签时我都看到 patientId 发生变化。

var nfc = angular.module('NfcCtrl', ['PatientRecordsService'])

nfc.controller('NfcCtrl', function($scope,  NfcService, PatientRecordsService) {
    $scope.tag = NfcService.tag;
    $scope.patientId = NfcService.patientId
    $scope.$watch(function() {
        return NfcService.patientId;
    }, function() {
        console.log("Inside watch");

        PatientRecordsService.getPatientRecords(NfcService.patientId)
        .then(
            function(response) {
                $scope.patientRecords = response
            },
            function(httpError) {
                throw httpError.status + " : " +
                    httpError.data;
            });
    }, true);
    $scope.clear = function() {
        NfcService.clearTag();
    };
});

nfc.factory('NfcService', function($rootScope, $ionicPlatform, $filter) {

    var tag = {};
    var patientId = {};

    $ionicPlatform.ready(function() {
        nfc.addNdefListener(function(nfcEvent) {
            console.log(JSON.stringify(nfcEvent.tag, null, 4));
            $rootScope.$apply(function(){
                angular.copy(nfcEvent.tag, tag);
                patientId = $filter('decodePayload')(tag.ndefMessage[0]);
            });
            console.log("PatientId: ", patientId);
        }, function() {
            console.log("Listening for NDEF Tags.");
        }, function(reason) {
            alert("Error adding NFC Listener " + reason);
        });
    });

    return {
        tag: tag,

        patientId: patientId,

        clearTag: function () {
            angular.copy({}, this.tag);
        }
    };

});

不确定我在这里遗漏了什么 - 请赐教!

更新 根据 rakslice 的建议,我创建了一个对象来将我的数据保存在工厂内,现在 html(有一些服务器端延迟)在扫描新的 NFC 标签时正确显示更新的值。

var nfc = angular.module('NfcCtrl', ['PatientRecordsService'])

nfc.controller('NfcCtrl', function($scope,  NfcService) {
    $scope.tagData = NfcService.tagData;
    $scope.clear = function() {
        NfcService.clearTag();
    };
});

nfc.factory('NfcService', function($rootScope, $ionicPlatform, $filter, PatientRecordsServi\
ce) {

    var tagData = {
        tag: null,
        patientId: null,
        patientRecords: []
    };

    $ionicPlatform.ready(function() {
        nfc.addNdefListener(function(nfcEvent) {
            //console.log(JSON.stringify(nfcEvent.tag, null, 4));
            $rootScope.$apply(function() {
                tagData.tag = nfcEvent.tag;
                tagData.patientId = $filter('decodePayload')(tagData.tag.ndefMessage[0]);
                PatientRecordsService.getPatientRecords(tagData.patientId)
                    .then(
                        function(response) {
                            tagData.patientRecords = response
                        },
                        function(httpError) {
                            throw httpError.status + " : " +
                                httpError.data;
                        });
            });
            console.log("Tag: ", tagData.tag);
            console.log("PatientId: ", tagData.patientId);
        }, function() {
            console.log("Listening for NDEF Tags.");
        }, function(reason) {
            alert("Error adding NFC Listener " + reason);
        })
    });

    return {
        tagData: tagData,
        clearTag: function() {
            angular.copy({}, this.tagData);
        }
    };
});

您的代码不会更新返回的 NfcService 中的 patientId 值,只会更新工厂函数中的局部变量 patientId

尝试将对您在工厂函数中返回的对象的引用保存为局部变量,并使用它来更新 patientId

例如,将对象的创建更改为将其放入局部变量中:

var nfcService = {
        tag: tag,

        patientId: patientId,

        clearTag: function () {
            angular.copy({}, this.tag);
        }
    };

...

return nfcService

然后更改patientId更新通过变量更改对象中的值。

nfcService.patientId = $filter('decodePayload')(tag.ndefMessage[0]);

更新:

您需要了解的关于 JavaScript 的基本事实是,当您将一个变量分配给另一个变量时,如果第一个变量具有原始数据值,第二个变量将获得该值的副本,因此更改第一个变量不会影响之后的第二个变量,但是如果第一个变量有一个对象引用,第二个变量将指向第一个变量指向的同一个对象,然后更改第一个变量中的对象将影响你通过第二个变量看到的东西,因为它在看同一个对象。

浏览器 JavaScript 控制台中的快速实验应该会给您思路:

> var a = 1;
> a
1
> var b = a;
> b
1
> a = 5;
> a
5
> b
1

对比

> var a = {foo: 1}
> var b = a
> a.foo = 5
> a.foo
5
> b.foo
5