Question

I'm writing a component that takes a String and converts it into a list of <span>s. Each <span> gets a String character and is assigned a random color.

The component invocation looks like this:

<span ng-repeat="char in ctrl.chars" style="color: {{ctrl.randomColor}};">
  {{char}}
</span>

And the component definition looks like this:

import 'package:angular/angular.dart';
import 'dart:math';

@NgComponent(
    selector: 'tokens',
    templateUrl: './component.html',
    cssUrl: './component.css',
    publishAs: 'ctrl',
    map: const {
      'text' : '@text',
    }
)
class TokensComponent {
  String text;

  List<String> get chars =>  text.split('');

  String get randomColor {
    var colors = ['red', 'green', 'yellow', 'blue'];
    return colors[new Random().nextInt(colors.length)];
  }
}

This works, but generates an error:

5 $digest() iterations reached. Aborting!
Watchers fired in the last 3 iterations:
...

It isn't clear to me just what is being watched here, beyond the getter I am defining. If I leave the code involving the Random in the getter, but simply return a hard-coded String, the error message goes away.

Any idea what is wrong here?

Was it helpful?

Solution

Binding a getter method with random return value seems like calling for all kind of weird stuff to happen.

From what I see, your intention seems to be to show all characters of a string in a different, random color - but not changing colors (meaning that the characters shouldn't constantly change their color) - is that right?

Unfortunately, the <span> isn't just created with the current return value of randomColor and then forgotten about - binding a property has the advantage that changes to the property are reflected in the view. Of course, since the "property" is a getter and has a random return value, it constantly changes, resulting in constant updates to the view.

If this error wouldn't occur to prevent this endless loop, all characters probably would have the same (rapidly changing) color.

OTHER TIPS

EDIT
This question has a good answer to the problem: AngularDart custom filter call() method required to be idempotent?

And alternative approach:

ORIGINAL
I'm not sure what you try to achieve but maybe it helps anyway

Screenshot of the result:

Screenshot

library main;

import 'dart:math';
import 'package:angular/angular.dart';
import 'package:di/di.dart';


class MyAppModule extends Module {
  MyAppModule() {
    type(TokensComponent);
  }
}

void main() {
  ngBootstrap(module: new MyAppModule());
}


@NgComponent(
    selector: 'tokens',
    template: '''<span ng-repeat="item in ctrl.items" style="color: {{item.color}};">
  {{item.char}}
</span>''',
    //cssUrl: './component.css',
    publishAs: 'ctrl',
    map: const {
      'text' : '@text',
    }
)
class TokensComponent {
  String text = 'abcdefg';

  List<Item> items = new List<Item>();
  TokensComponent() {
    text.split('').forEach((e) => items.add(new Item(e, randomColor)));
  }

  var colors = \['red', 'green', 'yellow', 'blue'\];

  String get randomColor {
    return colors\[new Random().nextInt(colors.length)\];
  }
}

class Item {
  Item(this.char, this.color);
  String char;
  String color;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top