$apply在angularJs中没有更新我的范围变量

$apply in angularJs not updating my scope variables

本文关键字:更新 我的 范围 变量 apply angularJs      更新时间:2023-09-26

到目前为止,我正在使用流星框架构建一个angular ionic应用程序,但我正在尝试使用$apply方法更新我的作用域,这不是更新我的范围,这是我的代码。更具体地说,上传图像后,用户调用addAvatar函数(),该函数使用fileReader API将图像转换为base64对象。反过来,必须使用$apply将其分配给editProfileController.cropImgSrc,但没有发生。

我正在尝试更新editProfileController.cropImgSrc 的范围

模板(指令)

<ion-view view-title="Profile Edit">
<div class="bar bar-header bar-positive">
    <h1 class="title">edit your profile</h1>
</div>
<ion-content overflow-scroll="true" class="has-header">
    <h4 style="color:#212121;font-family: 'proxima',sans-serif;">Edit profile</h4>
    <div class="row row-center">
        <div class="col col-25">
            <div>
                {{editProfileController.cropImgSrc}}
            </div>
        </div>
        <div class="col">
            <div class="button button-outline button-positive" ngf-select
                    ngf-change="editProfileController.addAvatar($files)"
                    ngf-multiple="false" ngf-allow-dir="false" ngf-accept="'image/*'"
                    ngf-drop-available="false">
                edit my display picture
            </div>
        </div>
    </div>
    <div class="list">
        <div class="list">
            <label class="item item-input">
                <span class="input-label">your name</span>
                <input type="text" ng-model="editProfileController.profile.name">
            </label>
            <label class="item item-input">
                <span class="input-label">your birthday</span>
                <input type="date" ng-model="editProfileController.profile.birthday">
            </label>
            <label class="item item-input item-select">
                <div class="input-label">
                    Gender
                </div>
                <select ng-model="editProfileController.profile.gender">
                    <option selected>Female</option>
                    <option>Male</option>
                    <option>Others</option>
                </select>
            </label>
        </div>
        <h5 style="color:#212121;font-family: 'proxima',sans-serif;" class="padding">Add a short Bio about you, Keep it interesting and simple!</h5>
        <label class="item item-input">
            <span class="input-label">Bio</span>
            <input type="text" placeholder="I am a storm trooper, fighting at star wars." ng-model="editProfileController.profile.bio">
        </label>
        <br>
        <div class="row padding">
            <div class="col">
                <button class="button button-outline button-positive button-block">
                    save my profile
                </button>
            </div>
        </div>
    </div>
</ion-content>

控制器

angular.module('appName').directive('profileedit',function(){
return{
    restrict: 'E',
    templateUrl: 'client/modules/profile-edit/profile-edit.html',
    controllerAs: 'editProfileController',
    controller: function($scope,$reactive){
        $reactive(this).attach($scope);
        this.helpers({
            cropImgSrc: function(){
                return ' ';
            }
        });
        this.addAvatar = function(files){
            if (files.length > 0) {
                var reader = new FileReader();
                reader.onload = function(e) {
                    $scope.$apply(function(){
                        this.cropImgSrc = e.target.result;
                    });
                };
                reader.readAsDataURL(files[0]);
            }
            else {
                this.cropImgSrc = undefined;
            }
        };
    }
}

});

解决方案将其附加到控制器定义之上的vm,var vm=此;

发生错误的原因是this的上下文在$scope.$apply方法调用中发生了更改。

请参阅:事件处理程序中的this上下文

一个简单的修复方法是将this的上下文保存在控制器定义顶部的变量中:

controller: function($scope,$reactive){
    // save context of this in a variable
    var vm = this;
    $reactive(this).attach($scope);
    this.helpers({
        cropImgSrc: function(){
            return ' ';
        }
    });
    this.addAvatar = function(files){
        if (files.length > 0) {
            var reader = new FileReader();
            reader.onload = function(e) {
                $scope.$apply(function(){
                    // vm still refers to the controller here
                    vm.cropImgSrc = e.target.result;
                });
            };
            reader.readAsDataURL(files[0]);
        }
        else {
            this.cropImgSrc = undefined;
        }
    };
}