简体   繁体   中英

What is the correct way to set $scope values on page load in a service scenario?

I have some log in information that needs to be displayed in more than one place on an Angular.js backed UI. To this end, I have set up two controllers to return a service object created in app.factory. The reason this has been created as a service is to have the two controllers share the same model object.

What I would like to do is use ng-bind to send initial model values with the page content on initial page load (so as to avoid any delay while values are retrieved). I wondered if the html element value on ng-bind would update the logInRegistrationUi object in this example, but rather the element content is overwritten with the initialisation value ('example initial value') on the logInRegistrationUi object.

    var app = angular.module('fr', []);

    app.factory('logInRegistrationUiService', function() {


        var logInRegistrationUi = {

            logInRegistrationVisible: false,
            userLoggedIn: false,
            userEmailAddress: 'example initial value'
        };

        var logInRegistrationUiService = {

            logInRegistrationUi: logInRegistrationUi
        };

        return logInRegistrationUiService;
    });

    app.controller('logInRegistrationFormController', function ($scope, logInRegistrationUiService) {

        $scope.logInRegistrationUi = logInRegistrationUiService.logInRegistrationUi;

        console.log('logInRegistrationVisible (logInRegistrationFormController): ' + $scope.logInRegistrationUi.logInRegistrationVisible)
    });

    app.controller('logInRegistrationStatusController', function ($scope, logInRegistrationUiService) {

        $scope.logInRegistrationUi = logInRegistrationUiService.logInRegistrationUi;

        console.log('logInRegistrationVisible (logInRegistrationStatusController): ' + $scope.logInRegistrationUi.logInRegistrationVisible)
    });

The HTML source on page load - The ng-bind spans have literal content, in an attempt to have the element value update the service model.

<div ng-controller="logInRegistrationStatusController">
    ....            
    <span ng-bind="logInRegistrationUi.userEmailAddress">test@example.com</span>
    ....            

</div>

<div ng-controller="logInRegistrationFormController">
    ....            
    <span ng-bind="logInRegistrationUi.userEmailAddress">test@example.com</span>
    ....            

</div>

But instead of the service model object having the userEmailAddress, property updated, the text 'example initial value' is rendered as per initial service value.

How can I have the service property logInRegistrationUi.userEmailAddress updated from the ng-bind element content rather than vice versa?

Update - Use of ng-init as per runTarm's answer produced the behaviour I was looking for, in a form that can be sent down with the page content on initial load

<div ng-controller="logInRegistrationStatusController">
    ....            
    <span ng-bind="logInRegistrationUi.userEmailAddress"  ng-init="logInRegistrationUi.userEmailAddress = 'test@example.com'"></span>
    ....            

</div>

<div ng-controller="logInRegistrationFormController">
    ....            
    <span ng-bind="logInRegistrationUi.userEmailAddress">test@example.com</span>
    ....            

</div>

But instead of the service model object having the userEmailAddress, property updated, the text 'example initial value' is rendered as per initial service value.

How can I have the service property logInRegistrationUi.userEmailAddress updated from the ng-bind element content rather than vice versa?

I'm still couldn't imagine why in the world you would want to do the opposite of the ng-bind , but here are two ways to set the model value from a view.

  1. You could write a custom directive like this:

     app.directive('reverseBind', function ($parse) { return { restrict: 'A', link: function (scope, element, attrs) { var setFn = $parse(attrs.reverseBind).assign; setFn(scope, element.text()) } } }) 

    and in html:

     <span reverse-bind="logInRegistrationUi.userEmailAddress">test@example.com</span> 
  2. or just use the ng-init :

     <span ng-init="logInRegistrationUi.userEmailAddress = 'test@example.com'">test@example.com</span> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM