изменение метода обнаружения изменений angular.dart

У меня есть контроллер, который определяет:

  • некоторые свойства, которые управляют тем, как выглядит мой пользовательский интерфейс
  • метод, который может быть вызван для изменения этих свойств

У меня также есть директива, которая получает метод контроллера в качестве параметра, чтобы иметь возможность его вызывать.

После angular.dart v0.9.9. никаких изменений в свойствах контроллера больше не обнаруживается. Поскольку я использую область только неявно, через свойства контроллера, я не уверен, должен ли/как я должен использовать «scope.context», упомянутый в разделе «критические изменения» angular.dart 0.9.9.

Как я могу это исправить?

[Обновить]

Ниже приведен код:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>test</title>
  </head>
  <body ng-cloak ng-controller="app-ctrl">
    <div>selections: {{ ctrl.selections }}</div>
    <div class="test-click" whenclicked="ctrl.goRight()">click</div>
    <script type="application/dart" src="/test/web/main.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

основной дротик

library test;
import 'package:angular/angular.dart';
import '../lib/src/app_ctrl.dart';
import '../lib/src/click_dir.dart';
void main() {
  ngBootstrap(module: new TestModule());
}
class TestModule extends Module {
  TestModule() {
    type(AppCtrl);
    type(TestClickDir);
  }
}

app_ctrl.dart

library app;
import 'package:angular/angular.dart';
/** AppCtrl */
@NgController(selector: '[ng-controller=app-ctrl]', publishAs: 'ctrl')
class AppCtrl {
  List selections;
  AppCtrl() {
    selections = ['a','a'];
  }
  void goRight() {
    selections.add('a');
  }
}

click_dir.dart

library clickable;
import 'package:angular/angular.dart';
import 'dart:html';
/** TestClickDir */
@NgDirective(selector: '.test-click', map: const {
  'whenclicked': '&click'
})
class TestClickDir implements NgAttachAware {
  Function click;
  Element self;
  TestClickDir(Element el) {
    self = el;
  }
  void attach() {
    self.onClick.listen((e) => click());
  }
}

person alearg    schedule 15.03.2014    source источник
comment
Вы получаете какую-либо ошибку? Не вижу необходимости что-то менять.   -  person Günter Zöchbauer    schedule 17.03.2014
comment
Если вы попробуете приведенный выше пример, сначала вы увидите, что список «выборки» содержит «аа». Если вы затем нажмете «щелчок», вызывается метод «goRight», «a» добавляется в список «выборов», но представление никогда не обновляется, тогда как до 0.9.9 оно обновлялось.   -  person alearg    schedule 17.03.2014
comment
Просто подсказка — вы можете использовать ng-click="ctrl.goRight()" вместо атрибута whenclicked. Я могу воспроизвести, но понятия не имею о причине.   -  person Günter Zöchbauer    schedule 17.03.2014


Ответы (3)


Я предполагаю, что это связано с оптимизацией, потому что просмотр коллекций стоит дорого. Хотя тоже может быть баг.

Я полагаю, вы используете это только для целей отладки? Немного другого результата можно легко добиться с помощью:

{{ ctrl.selections | json }} // prints: ["a","a","a","a","a","a","a"]

просто нашел, что это работает лучше

{{ ctrl.selections.toString() }} // prints: [a, a, a, a, a, a, a]
person Günter Zöchbauer    schedule 17.03.2014

Я считаю, что это ошибка, потому что даже watch не срабатывает при изменении длины списка. Если вы помещаете в выборку новый список (selection = ['a', 'a', 'a']), то изменение обновляется.

Вот рабочий пример, где selections = selections; заставляет его работать. Конечно, _scope.watch не нужен, он здесь просто для примера нового синтаксиса (синтаксис watch изменился в версии 0.9.9).

РЕДАКТИРОВАТЬ: ЭТОТ ПРИМЕР НЕ РАБОТАЕТ. Я не знаю, почему это сработало, когда я тестировал его. Я должен был сделать некоторую ошибку ранее, но в любом случае это не работает. Я добавил рабочее решение (https://groups.google.com/forum/#!msg/angular-dart/v_t2RUz9lrU/HY7DzAj554sJ)

  AppCtrl(Scope _scope) {
    _scope.watch('selections', (newValue, oldValue) => print("selections: $newValue"), context: this);
    selections = ['a','a'];
  }

  void goRight() {
    selections.add('a');
    selections = selections;
    // or
    selections.add('');
    selections[selections.length-1]='a';
    // following works, the code above don't work
   selections = (selections..add('a')).toList();
  }
person grohjy    schedule 17.03.2014
comment
Это сделано намеренно. Сегодня я видел обсуждение в репозитории AngularDart GitHub (попробуйте найти пост еще раз). Для коллекций отслеживаются только изменения личности. За ng-repeat немного больше наблюдают. - person Günter Zöchbauer; 17.03.2014
comment
Я понимаю, что изменения в элементах списка не отслеживаются (см.: stackoverflow.com/a/20962381/2777805), но я думаю, что если количество элементов в списке изменится, его следует уведомить. Я отредактировал свой ответ и добавил новое рабочее решение (// или ...). Это решение ИМО такое же, как add('a'), т.е. содержимое списка меняется в обоих случаях одинаково. - person grohjy; 18.03.2014

Посмотрите здесь, чтобы узнать, что такое продолжается.

Насколько я понимаю, изменение никогда не сработает, потому что список не меняет личность. Раньше этот код работал, потому что ререндер, видимо, всегда проводился. Это уже не так по соображениям эффективности.

person alearg    schedule 17.03.2014
comment
Эффективность хорошая, и теперь мы знаем, как запустить изменение, если это необходимо (просто присвоить исходное значение одного элемента самому себе). Теперь я должен проверить, как работает ng-repeat. - person grohjy; 18.03.2014
comment
ng-repeat работает нормально, но требует ng-repeat="selection in ctrl.selections track by $index", как указано в вашей ссылке. Мое предыдущее решение не работало, я где-то ошибся. Теперь мой ответ обновлен рабочим решением. - person grohjy; 18.03.2014