Обновление $ scope из $ scope.function ()

0

Прежде всего, мне жаль, если сообщение слишком длинное. Кроме того, на всякий случай это каким-то образом мешает ответам, которые вы можете мне дать, я не определяю свой контроллер обычным способом. Вместо этого я следую http://www.technofattie.com/2014/03/21/five-guidelines-for-avoiding-scope-soup-in-angular.html и делаю:

var game_1 = function($scope){
  var _this = this;
  //some code
  $scope.someFunction = function() {
    _this.someFunction() ;
  } ;
} ;
game1.prototype.someFunction = function() {
  //some code
} ;
game_1.$inject = ['$scope'] ;
app.controller('game_1', game_1) ;

В моем HTML у меня есть объект с атрибутом ng-show="checkRare". Теперь у меня есть набор функций, которые работают как матрешка:

Определено внутри контроллера:

this.promptElement = function(message) {
    var input = prompt(message) ;
    if ( input === null ) {
        this.resetCell(this.cellIJ) ;
        return false ;
    } else if ( input === '' ) {
        this.resetCell(this.cellIJ) ;
        return '' ;
    } else {
        return input.toUpperCase() ;
    }
} ;
//some more code
$scope.function1 = function(i,j,F) {
    _this.function1(i,j,F) ;
} ;
$scope.function2A = function(j) {
    _this.function2A(j) ;
} ;
$scope.function2B = function(i,F) {
    _this.function2B(i,F) ;
} ;
$scope.function3A = function() {
    _this.function3A() ;
} ;
$scope.function3B = function() {
    _this.function3B() ;
} ;
$scope.function4 = function() {
    $scope.checkRare = true ; //THE PROBLEM LIES HERE
    _this.function4() ;
} ;

И снаружи, у меня есть:

game_1.prototype.function1 = function(i,j,F) {
    //some code 
    this.inputElement = this.promptElement('Enter element name') ;
    //some more code
} ;
game_1.prototype.function2A = function(j) {
    //some code
    for ( var i = 1 ; i < 8 ; i++ ) {
        this.function1(i,j) ;
        if ( this.inputElement === false ) { return ; }
    }
} ;
game_1.prototype.function2B = function(i,F) {
    //some code
    for ( var j = j0 ; j < jF ; j++ ) {
        this.function1(i,j,F) ;
        if ( this.inputElement === false ) { return ; }
    }
} ;
game_1.prototype.function3A = function() {
    //some code
    for ( var j = 1 ; j < 19 ; j ++ ) {
        this.function2A(j) ;
        if ( this.inputElement === false ) { return ; }
    }
} ;
game_1.prototype.function3B = function() {
    //some code
    for ( var i = 6 ; i < 8 ; i++ ) {
        this.function2B(i,true) ;
        if ( this.inputElement === false ) { return ; }
    }
} ;
game_1.prototype.function4 = function() {
    //some code
    this.function3A() ;
    if ( this.inputElement === false ) { return ; }
    this.function3B() ;
} ;

Однако, как кто-то предложил в другом вопросе, который я задал, область $scope не обновится до завершения всей функции, поэтому я не смогу увидеть эффекты $scope.checkRare = true до конца. Для того, чтобы это было первым делом, я попытался использовать $scope.$apply, но я получаю ошибку $apply already in progress (что, кстати, я также иногда получаю случайно). Я также пробовал использовать $timeout и " safeApply " (https://coderwall.com/p/ngisma/safe-apply-in-angular-js), но никто не работал.

Итак, любые идеи о том, как увидеть результат $scope.checkRare = true до того, как остальная часть функции $scope.checkRare = true свою работу? И, как второстепенный вопрос, может кто-нибудь сказать мне, почему я иногда получаю $apply already in progress даже когда я не эксплицитно использую $scope.$apply Apply?

Заранее спасибо! И снова, извините за длинный пост! :)

  • 0
    Я не уверен, что смогу точно ответить на ваш вопрос о $apply без полного рабочего примера. Существует ряд факторов, которые могут вызвать указанную вами ошибку.
  • 0
    Здесь я сделал скрипку (надеюсь, я сделал это правильно): jsfiddle.net/MarioMG/7zeae1eu/3 Все еще есть некоторые ошибки, о которых я должен позаботиться, но это в основном все.
Показать ещё 3 комментария
Теги:

1 ответ

1
Лучший ответ

Я, возможно, не полностью понял ваш вопрос, но я думаю, что вы ищете что-то вроде этого:

...
$scope.doSomething = function(){
  $scope.checkRare = true;
  $timeout(function(){
    // check for results of setting $scope.checkRare
  });
}
...

Чтобы понять, почему это работает, это помогает понять цикл событий JavaScript. Короче говоря, DOM не обновляется до конца итерации цикла события. Каждая итерация по циклу не заканчивается до тех пор, пока механизм JavaScript не завершит выполнение кода. Когда вы помещаете код в обратный вызов с тайм-аутом (без задержки), вы по существу говорите движку JavaScript, чтобы он выполнял этот обратный вызов в следующей итерации цикла (таким образом, чтобы DOM обновлялся до запуска обратного вызова).

  • 0
    Вот и все! Огромное спасибо! Я ошибся, я думал, что должен обернуть $scope.checkRare = true внутри $timeout вместо остальной части функции. Теперь, когда я сделал это, как вы говорите, все работает! : D

Ещё вопросы

Сообщество Overcoder
Наверх
Меню