2

我想在一个对象属性(my_json)中保存一个从外部文件加载的 JSON 列表。使用此代码 my_json 属性始终等于 null :{

在此先感谢您的帮助 :)

@CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{

  void click_menu_item(String label) {
    shadowRoot.querySelector('#page_name').text = label;
  }

  MyCustomTag.created() : super.created(){

    var menu_list = new MenuList('menu_items.json');

    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  }
}

class MenuList {
  String path;
  List my_json;

  MenuList(String path) {
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
    ..open('GET', path)
    ..onLoadEnd.listen((e) => requestComplete(httpRequest))
    ..send('');
  }

  requestComplete(HttpRequest request) {
    // request.status is 200 
    // request.responseText is 
    // "[ {"icon": "settings", "label": "Signin", "main_page": "signin-element"}, {"icon": "home", "label": "About", "main_page": "about-page-element"} ]" 
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
}
4

3 回答 3

2

这是您需要的代码:

HttpRequest.request(path, responseType: 'json').then((HttpRequest request) {
  var json = request.response;
});

请注意,目前 Dartium 中存在一个错误:

https://code.google.com/p/dart/issues/detail?id=20129

作为一种解决方法,您可以省略 responseType 参数并使用 request.responseText。

问候,罗伯特

于 2014-07-22T15:07:50.943 回答
1

您的 MenuList 类可能看起来像

class MenuList {
  String path;
  List my_json;

  static Future<MenuList> create(String path) {
    return new MenuList()._load(path);
  }

  Future<MenuList>_load(String path) {
    Completer completer = new Completer();
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
        ..open('GET', path)
        ..onLoadEnd.listen((e) {
          requestComplete(httpRequest);
          completer.complete(this);
        })
        ..send('');
    return completer.future;
  }

  requestComplete(HttpRequest request) {
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
}

和 MyCustomTag 的构造函数

void attached() {
  super.attached();

  var menu_list;
  MenuList.create('menu_items.json')
  .then((ml) {
    menu_list = ml;
    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  });
}

我还没有实际测试过这段代码,但至少分析器很满意。

于 2014-07-22T15:17:50.477 回答
1

解决方案来自罗伯特。我尝试在将 JSON 列表结果分配给之前读取对象属性。所以我总是有一个空属性......为了避免这种情况,我向我的 HttpRequest.open 添加了一个可选参数 async : ..open('GET', path, async:false )

这是最终代码。

@CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{

  void click_menu_item(String label) {
    shadowRoot.querySelector('#page_name').text = label;
  }

  MyCustomTag.created() : super.created(){

    var menu_list = new MenuList('menu_items.json');

    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  }
}

class MenuList {
  String path;
  List my_json;

  MenuList(String path) {
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
    ..open('GET', path, async:false)
    ..onLoadEnd.listen((e) => requestComplete(httpRequest))
    ..send('');
  }

  requestComplete(HttpRequest request) {
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
} 
于 2014-07-22T16:38:08.617 回答