2015-01-31 3 views
1

Я пытаюсь найти способ интерполировать строку с в аннотации, так как параметры класса аннотаций конструктора должны быть постоянными, я должен был пропустить $, а затем заменить '\$' с '$' когда это мне нужно интерполировать следующий пример проясняет, что я пытаюсь сделатьInterpolate Строка в пределах класса аннотаций

import 'dart:mirrors'; 

    void main() { 
      var c = new Chicken('aaaa','blue',99); 
      var templateValue = (reflectClass(Chicken).metadata.where((a)=>a.reflectee.runtimeType == Template).first.reflectee as Template).value; 
      print(interpolater.interpolate(c,templateValue)); 
     } 

     class Template{ 
      final String value; 
      const Template(this.value); 
     } 

     @Template('<div>name:\${context.name} color:\${context.color} age:\${context.age}</div>') 
     class Chicken{ 
      String name; 
      String color; 
      int age; 
      Chicken(this.name,this.color,this.age); 
     } 

     class interpolater{ 
      static String interpolate(Object context,String s){ 
      s = s.replaceAll('\\\$', '\$'); 
      return s; 
      } 
     } 

, но это не похоже на работу, в любом случае, чтобы сделать что-то вроде этой работы?

ответ

2

Вам нужно обернуть строку в функции как templateStr ниже:

import 'dart:mirrors'; 

class Context { 
    String name = "some name"; 
    String color = "some color"; 
    int age = 15; 
} 

void main() { 
    var c = new Chicken('aaaa','blue',99); 
    var templateValue = (reflectClass(Chicken).metadata.where((a)=>a.reflectee.runtimeType == Template).first.reflectee as Template).value(c); 
    print(templateValue); 
} 

class Template{ 
    final Function value; 
    const Template(this.value); 
    String getValue(context) => value(context); 
} 

String templateStr(context) => '<div>name:${context.name} color:${context.color} age:${context.age}</div>'; 

@Template(templateStr) 
class Chicken{ 
    String name; 
    String color; 
    int age; 
    Chicken(this.name,this.color,this.age); 
} 
+0

отлично, но как насчет того, когда придет время интерполяции? – FPGA

+0

yes thats my interolate, но ничего не происходит, он печатает строку, как это – FPGA

+0

См. Http://stackoverflow.com/questions/11886796 –

2

Строка интерполяции грамматическая часть Дарт, он распознается при анализе.

Если вы берете строку и заменяете «\ $» в строке «$», вы просто получите строку с «$» в ней. Это не интерполяция во время компиляции, поэтому теперь это не интерполяция.

Вы можете думать о строковой интерполяции, как «$ a foo $ b», как сокращение для "" + a.toString() + " foo " + b.toString() + "". Интерполяция строк - это строковое выражение , но это не сама строка - каждый раз, когда она оценивается, она вычисляется в новой строке. (Ну, интерполяция констант строки времени компиляции является строковым значением во время выполнения, потому что она оценивается только один раз во время компиляции).

Если вы хотите сделать шаблон, который заполняется во время выполнения, то вы должны сделать код, который делает заполнение.

Одним из вариантов является не использовать строку, но вместо этого используйте функция в аннотации:

// Top-level function is compile-time constant. 
myTemplate(context) => 
    '<div>name:${context.name} color:${context.color} age:${context.age}</div>'; 

@Template(myTemplate) 
class Chicken {...} 

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

(Если у вас есть доступ к аннотации класса, почему бы вам просто не добавить метод в класс вместо этого. Тогда вам не понадобятся зеркала. Или если вы не хотите добавлять метод к объекту , возможно, сделайте его статическим, а затем просмотрите его с помощью зеркал)