2016-03-03 9 views
9

UPDATE:Here is a link to reproduce the problemKendo UI: una fonte di dati, due widget

RELATIVA:This is another question of mine where similar problems are happening with Kendo UI Map, maybe it could help someone figure this one out! Ha una mancanza ed una versione di lavoro.


Io uso DataSource, DropDownList e Map dell'interfaccia utente di Kendo in un'applicazione angolare a pagina singola.

Desidero utilizzare lo stesso oggetto DataSource sia per DropDownList che per la mappa. Tuttavia, la mappa si comporta in modo molto imprevedibile.

  1. Quando ho messo la DropDownList prima mappa nel modello, solo il DropDownList ottiene popolata. L'ispezione del traffico di rete rivela che in effetti è stata fatta solo una richiesta. Quando metto per primo la mappa, entrambi vengono popolati e vengono fatte due richieste.
  2. Quando non utilizzo alcuna promessa in transport.read, ma si chiama semplicemente options.success immediatamente con un valore statico, tutto funziona come previsto. Sono state fatte due chiamate.

Mi ci sono passato i capelli per tutta la giornata di lavoro, quindi qualsiasi aiuto è molto apprezzato.

Il servizio di origine dati:

m.factory('ourDataSource', function(foo, bar, baz) { 
    return new kendo.data.DataSource({ 
     transport: { 
      read: function(options) { 
       foo().then(function (result) { 
        return bar(result); 
       }).then(function (result) { 
        return baz(result); 
       }).then(function (result) { 
        options.success(result); 
       }).catch(function (err) { 
        options.error(err); 
       }); 
      } 
     } 
    }); 
}); 

Il controllore:

m.controller('ourController', ['ourDataSource', function(ourDataSource) { 

    // set the data source of the dropdownlist 
    this.ourDataSource = ourDataSource; 

    // set up the map layers 
    this.mapLayers = [{ 
     type: 'tile', 
     urlTemplate: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/#= zoom #/#= y #/#= x #', 
    }, { 
     type: 'marker', 
     dataSource: ourDataSource, // the same data source as before 
     locationField: 'Position', 
     titleField: 'Title' 
    }]; 
}]); 

La vista:

<div ng-controller="ourController as ctrl"> 

    <select kendo-drop-down-list 
      k-data-text-field="'Title'" 
      k-data-value-field="'Title'" 
      k-data-source="ctrl.ourDataSource"></select> 

    <div kendo-map 
     k-zoom="2" 
     k-center="[1, 1]" 
     k-layers="ctrl.mapLayers"> 
    </div> 

</div> 

Che cosa mi manca qui?

+0

Ma, si _don't want_ due richieste di lettura. È un'origine dati condivisa, quindi, perché vorresti che richieda gli stessi dati due volte? Per quanto riguarda il motivo per cui non è vincolante per i dati, probabilmente avremmo bisogno di un esempio pubblico che duplica questo comportamento. È difficile dedurre così com'è. – Brett

+0

@Brett: In effetti, non desidero due richieste, ma anche quando disattivo autoBind e chiamo 'fetch' manualmente, il risultato è lo stesso. Sentivo che sarebbe stato più facile capire se riducevo il caso di test al modo più semplice possibile. Vedrò se riesco a creare un esempio pubblico. – damd

+0

Potrebbe essere dovuto al fatto che 'ourDataSource' è una factory che sta restituendo un oggetto __new__ datasource? Prova a restituirlo come un singleton. – Brett

risposta

0

Credo che questo potrebbe essere un bug nel widget di UI Map di Kendo, poiché il comportamento che si verifica qui non è affatto quello che ci si aspetterebbe. Tuttavia, ho una soluzione alternativa. Anziché restituire l'origine dati come oggetto singleton, restituirlo come una funzione. Questo probabilmente non è l'ideale, ma funziona.


angular.module('ourModule', ['kendo.directives']) 
.factory('getDataSource', function ($q) { 
    return function() { // return a function that creates a new data source 
    return new kendo.data.DataSource({ 
     transport: { 
     read: function (options) { 
      $q.when([ 
      {Position: [1, 1], Title: 'First place'}, 
      {Position: [10, 10], Title: 'Second place'} 
      ]).then(function (result) { 
      options.success(result); 
      }); 
     } 
     } 
    }); 
    }; 
}) 
.controller('ourController', function (getDataSource) { 
    this.ourDataSource = getDataSource();  
    this.mapLayers = [{ 
    type: 'tile', 
    urlTemplate: '...removed for brevity...' 
    }, { 
    type: 'marker', 
    dataSource: getDataSource(), 
    locationField: 'Position', 
    titleField: 'Title' 
    }]; 
}); 
0

fabbrica in gran parte utilizzato per creare le istanze su richiesta. Vedere questo esempio

var app = angular.module('ourModule', ['kendo.directives']); 
 

 
app.factory('dataSourceFactory', function($q) { 
 

 
    function dataSourceFactory() {} 
 

 
    dataSourceFactory.prototype = { 
 
    contentTypes: function() { 
 
    return new kendo.data.DataSource({ 
 
    transport: { 
 
     read: function(options) { 
 
     $q.when(
 
     [{ 
 
      Position: [1, 1], 
 
      Title: 'First place' 
 
     }, { 
 
      Position: [10, 10], 
 
      Title: 'Second place' 
 
     }]) 
 
     .then(function(result) { 
 
     options.success(result); 
 
     }); 
 
     } 
 
    } 
 
    }) 
 
    } 
 
    }; 
 

 
    return dataSourceFactory; 
 
}); 
 

 
app.controller('ourController', ['$scope', 'dataSourceFactory', 
 

 
    function($scope, dataSourceFactory) { 
 

 
    var dataSourceFactory = new dataSourceFactory(); 
 

 
    $scope.mapLayers = [{ 
 
    type: 'tile', 
 
    urlTemplate: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/#= zoom #/#= y #/#= x #', 
 
    }, { 
 
    type: 'marker', 
 
    dataSource: dataSourceFactory.contentTypes(), // the same data source as before 
 
    locationField: 'Position', 
 
    titleField: 'Title' 
 
    }]; 
 

 
    $scope.ourDataSource = dataSourceFactory.contentTypes(); 
 
    } 
 
]);
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css"> 
 
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css"> 
 
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css"> 
 
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css"> 
 

 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
 
    <script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script> 
 
    <script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script> 
 
    <script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script> 
 

 
<div ng-app="ourModule"> 
 
    
 
    <div ng-controller="ourController"> 
 
    \t \t  
 
    <kendo-drop-down-list k-data-source="ourDataSource" 
 
          k-data-text-field="'Title'" 
 
          k-data-value-field="'Title'"> 
 
    </kendo-drop-down-list> 
 

 
    <kendo-map k-zoom="2" 
 
       k-layers="mapLayers"> 
 
    </kendo-map> 
 
    
 
    </div> 
 
</div>

Vai a questa JSFiddle demo