2017-02-18 18 views
0

Я использую NativeScript + JavaScript. Я пытаюсь заполнить ListView данными JSON-Data из API. Веб-запрос работает так, как должно, но я не могу добавить данные, полученные с сервера, в ListView. Но я могу добавить жестко закодированные данные в ListView.Как заполнить ListView в NativeScript данными JSON из WebService?

Вот код моего ViewModel:

"use strict"; 
var config = require ("../../shared/config"); 
var observableModule = require("data/observable"); 
var observable_array_1 = require("data/observable-array"); 
var arrayOfDataItems; 

var ViewModel = (function() { 

function ViewModel() { 
    this.initDataItems(); 
} 
Object.defineProperty(ViewModel.prototype, "dataItems", { 
    get: function() { 
     return this._items; 
    }, 
    enumerable: true, 
    configurable: true 
}); 
ViewModel.prototype.onAddItemClick = function (args) { 
    this._items.push(new DataItem("1","Fooo","Bar")); 
}; 

ViewModel.prototype.initDataItems = function (args) { 
    this._items = new observable_array_1.ObservableArray(); 

    //conifg.apiUrl holds the URL where i make the GET Request 
    //I can populate the ListView if i write this._items.push(new DataItem("1","Lorem","Ipsum" here 
    return fetch(config.apiUrl + "competition") 
    .then(function(response) { 
     return response.json();   
    }).then(function(data) { 
     for (var i = 0; i < data.length; i++) { 
      //I can't populate the ListView here when I get the response from the server    
      this._items.push(new DataItem(data[i].id,data[i].name,"Useless Description")); 
     } 
    }); 
}; 

return ViewModel; 
}()); 
exports.ViewModel = ViewModel; 

var DataItem = (function (_super) { 
__extends(DataItem, _super); 
function DataItem(id, name, description) { 
    _super.call(this); 
    this.id = id; 
    this.itemName = name; 
    this.itemDescription = description; 
} 
Object.defineProperty(DataItem.prototype, "id", { 
    get: function() { 
     return this.get("_id"); 
    }, 
    set: function (value) { 
     this.set("_id", value); 
    }, 
    enumerable: true, 
    configurable: true 
}); 
Object.defineProperty(DataItem.prototype, "itemName", { 
    get: function() { 
     return this.get("_itemName"); 
    }, 
    set: function (value) { 
     this.set("_itemName", value); 
    }, 
    enumerable: true, 
    configurable: true 
}); 
    Object.defineProperty(DataItem.prototype, "itemDescription", { 
    get: function() { 
     return this.get("_itemDescription"); 
    }, 
    set: function (value) { 
     this.set("_itemDescription", value); 
    }, 
    enumerable: true, 
    configurable: true 
}); 
return DataItem; 
}(observableModule.Observable)); 
exports.DataItem = DataItem; 

Это код моего контроллера

var BasePage = require("../../shared/BasePage"); 
var topmost = require("ui/frame").topmost; 




var CompetitionPage = function() {}; 
CompetitionPage.prototype = new BasePage(); 
CompetitionPage.prototype.constructor = CompetitionPage; 

var viewModel = require("~/views/results/observable-array-model"); 

CompetitionPage.prototype.onPageLoaded = function(args) { 
    var page = args.object; 
    page.bindingContext = new viewModel.ViewModel 
} 

module.exports = new CompetitionPage(); 

А вот XML мой ListView

 <GridLayout loaded="onPageLoaded" orientation="vertical" rows="50, *"> 
     <StackLayout orientation="vertical" backgroundColor="#f8f8f8"> 
     <StackLayout row="0" orientation="horizontal" horizontalAlignment="center"> 
       <Button text="Add" tap="{{onAddItemClick}}" ios:margin="0"/> 
       <Button text="Del" tap="{{onRemoveItemClick}}" ios:margin="10"/> 
       <Button text="Update" tap="{{onUpdateItemClick}}" ios:margin="10"/> 
       <Button text="Reset" tap="{{onResetClick}}" ios:margin="10"/> 
      </StackLayout> 
      </StackLayout> 
      <lv:RadListView items="{{ dataItems }}" row="1" id="ls"> 
       <lv:RadListView.listViewLayout> 
        <lv:ListViewLinearLayout scrollDirection="Vertical"/> 
       </lv:RadListView.listViewLayout> 
       <lv:RadListView.itemTemplate> 
        <StackLayout orientation="vertical"> 
         <Label fontSize="20" text="{{ _itemName }}"/> 
         <Label fontSize="14" text="{{ _itemDescription }}"/> 
         <Label fontSize="10" text="{{ _id }}" /> 
        </StackLayout> 
       </lv:RadListView.itemTemplate> 
      </lv:RadListView> 

     </GridLayout> 
+0

Существует много кода там. Можете ли вы следовать рекомендациям по созданию минимального полного проверяемого примера. http://stackoverflow.com/help/mcve –

+0

Я не вижу никакого запроса «веб-службы» в своих фрагментах кода. Можете ли вы показать нам, как вы выполняете этот запрос и как сопоставляете ответ, который должен быть передан в свойство элементов RadListView? –

+0

@VladimirAmiorkov Он должен работать с двухсторонним привязкой Data ObservableArray, который я создаю. Когда я вызываю onAddItemClick через кнопку из представления, я могу фактически добавить что-то в ListView. Я прокомментировал свой код, чтобы отметить, где я делаю запрос в webservice. –

ответ

0

Похоже вы не пропустите правильныйthis.then операции выборки.

Просто сохраните текущее это в WeakRef и использовать его в функции обратного вызова:

ViewModel.prototype.initDataItems = function (args) { 
    this._items = new observable_array_1.ObservableArray(); 

    var that = new WeakRef(this); 

    return fetch(config.apiUrl + "competition") 
    .then(function(response) { 
     return response.json();   
    }).then(function(data) { 
     for (var i = 0; i < data.length; i++) { 

      that.get()._items.push(new DataItem(data[i].id,data[i].name,"Useless Description")); 
     } 
    }); 
}; 
+0

Вы были правы. Это решило проблему. Благодарю. –