2013-07-24 3 views
7

Sto seguendo l'articolo Using Kendo UI with MVC4 WebAPI OData and EF. Dopo aver installato KendoUI e assicurandosi che tutti i riferimenti sono impostati, digito tre personaggi, e ottengo il seguente errore:Errore nel rendering dei dati con il completamento automatico JavaScript/KendoUI - L'oggetto n. <Object> non ha alcun metodo 'slice' - come risolvere?

Uncaught TypeError: Object # has no method 'slice'

radice del problema

Per salvare la lettura attraverso gli aggiornamenti: Attraverso il debug I trovato che il problema è che JS si aspetta di analizzare un array, dove non è disponibile nei dati - alla radice. Nella gerarchia dei dati, è di un livello nella

problema originale

Ho ripulito kendo.web.min.js e l'errore è in corso attorno alla riga 3498:.

success: function (n) { 
    var i = this, 
     r = i.options; 
    return i.trigger(wt, { 
     response: n, 
     type: "read" 
    }), n = i.reader.parse(n), i._handleCustomErrors(n) ? (i._dequeueRequest(), t) : (i._pristine = et(n) ? e.extend(!0, {}, n) : n.slice ? n.slice(0) : n, i._total = i.reader.total(n), i._aggregate && r.serverAggregates && (i._aggregateResult = i.reader.aggregates(n)), n = i._readData(n), i._pristineData = n.slice(0), i._data = i._observe(n), i._addRange(i._data), i._process(i._data), i._dequeueRequest(), t) 

Il Kendo widget UI stanno caricando bene così come il css:

<link href="~/Content/kendo/kendo.common.min.css" rel="stylesheet" /> 
<link href="~/Content/kendo/kendo.default.min.css" rel="stylesheet" /> 
<script src="~/Scripts/jquery-1.9.1.min.js"></script> 
<script src="~/Scripts/kendo/kendo.web.min.js"></script> 
<script src="~/Scripts/kendo/kendo.aspnetmvc.min.js"></script> 
<script src="~/Scripts/appScripts.js"></script> 

E sto vedendo lo stesso errore sia con l'utilizzo del rasoio MVC aiutante/Extensio n:

@(Html.Kendo().AutoComplete() 
    .Name("userAutoComplete")     // specifies the "id" attribute of the widget 
    .DataTextField("USERNAME") 
    .DataSource(source => 
     { 
      source.Read(read => 
       { 
        read.Url("/api/user"); 
       }) 
        .ServerFiltering(true);  // if true, the DataSource will not filter the data on the client 
     } 
    ) 
) 

e attraverso direttamente tramite JS:

/// <reference path="kendo/kendo.aspnetmvc.min.js" /> 
/// <reference path="kendo/kendo.core.min.js" /> 
/// <reference path="kendo/kendo.autocomplete.min.js" /> 
/// <reference path="kendo/kendo.web.min.js" /> 

$(document).ready(function() { 
    // load up KendoUI 

    // gets data from /api/user 
    var dataSource = new kendo.data.DataSource({ 
     transport: { 
      read: { 
       url: "/api/user" 
      } 
     } 
    }); 

    $("#userSearch").kendoAutoComplete({ 
     dataSource: dataSource, 
     dataTextField: "USERNAME", 
     minLength: 3 
    }); 

    $("#userSearch").on('input', function() { 
     console.log($("#userSearch").val()); 
    }); 

}); // $(document).ready() 

Sono sicuro che questo è qualcosa di semplice che io possa mancare. Ho provato sia con il web che con tutti i file js.

Qualsiasi assistenza sarebbe gradita.

- AGGIORNAMENTO -

L'unica vera html manca che il contenuto è il <input id="userAutoComplete" />

ho creato una nuova soluzione e una visione molto semplice, basata su uno degli esempi Kendo UI che ottiene i dati JSON da http://api.geonames.org e ottiene lo stesso errore.

ho pensato che utilizzando il più recente libreria JS (//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js possono essere stati causa di un problema così ho provato la 1.7 lib stesso problema:.

@using Kendo.Mvc.UI 

@{ 
    Layout = null; 
} 

<!DOCTYPE html> 

<html> 
<head> 
    <meta name="viewport" content="width=device-width" /> 
    <title>Index</title> 

    <link rel="stylesheet" href="@Url.Content("~/Content/kendo.common.min.css")"> 
    <link rel="stylesheet" href="@Url.Content("~/Content/kendo.default.min.css")"> 
    <link rel="stylesheet" href="@Url.Content("~/Content/kendo.dataviz.min.css")"> 

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script> 

    <script src="@Url.Content("~/Scripts/kendo.web.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/kendo.aspnetmvc.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/kendo.dataviz.min.js")"></script> 

    <script type="text/javascript"> 

     $(document).ready(function() { 
      $("#autoComplete").kendoAutoComplete({ 
       minLength: 6, 
       dataTextField: "title", 
       filter: "contains", 
       dataSource: new kendo.data.DataSource({ 
        transport: { 
         read: { 
          url: "http://api.geonames.org/wikipediaSearchJSON", 
          data: { 
           q: function() { 
            return $("#autoComplete").data("kendoAutoComplete").value(); 
           }, 
           maxRows: 10, 
           username: "demo" 
          } 
         } 
        }, 
        schema: { 
         data: "geonames" 
        } 
       }), 
       change: function() { 
        this.dataSource.read(); 
       } 
      }) 
     }); 

    </script>  


</head> 
<body> 
    <div> 

     <input id="autoComplete"/> 

    </div> 
</body> 
</html> 

- AGGIORNAMENTO -

Utilizzando la codice sopra, sono tornato indietro e l'ho provato di nuovo - ha funzionato bene. Dopo aver provato diverse volte, ho riscontrato lo stesso problema. Ciò è dovuto al fatto che i dati JSON validi cambiano come segue:

{"status":{"message":"the daily limit of 30000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application.","value":18}} 

... che mi ha portato a guardare la formattazione dei dati provenienti dal mio API (guardando in Fiddler:

Invece di:

JSON --- {... dati. ..

è

JSON 
---$id=1 
---$values 
------{} 
---------$id=2 
---------CREATEDATETIME... 
[email protected] 
---------GROUPS 
------------$id=... 
------------$id=... 
---------USERNAME=someusername 
------{} 
---------$id=4 
. 
. 
. 

Quindi l'errore è causato dalla matrice non essere accessibile in cui la si è aspettato - invece della radice, è un livello profondo.

Come si ottiene l'associazione dei dati a livello di un livello anziché alla radice dell'oggetto JSON?

Grazie.

+0

può anche pubblicare il tuo codice HTML? #userSearch è un elemento ? – AntouanK

risposta

3

La soluzione per questo era di attraversare la gerarchia dei dati descrivendo il formato del risultato.

Dal momento che la matrice è contenuta in valori $, ho usato la definizione seguente origine dati/schema:

// gets data from /api/user 
    var dataSource = new kendo.data.DataSource({ 
     transport: { 
      read: { 
       url: "/api/user" 
      } 
     }, 
     schema: {        // describe the result format 
      data: function(data) {    // the data which the data source will be bound to is in the values field 
       console.log(data.$values); 
       return data.$values; 
      } 
     } 
    }); 

Una cosa che sarebbe bello è quello di essere in grado di aggiungere un tipo di schema di dati nel helper Razor - quale doesn't seem to be supported at this time.

Così, il seguente ancora non avrebbe funzionato:

@(Html.Kendo().AutoComplete() 
     .Name("userAutoComplete")     // specifies the "id" attribute of the widget 
     .Filter("startswith") 
     .Placeholder("Type user name...") 
     .DataTextField("USERNAME") 
     .DataSource(source => 
      { 
       source: 
        source.Read(read => 
         { 
          read.Url("/api/user"); 
         }) 
         .ServerFiltering(true);  // if true, the DataSource will not filter the data on the client 

      } 
     ) 
) 
2

Questo ha funzionato per me:

var dataSource = new kendo.data.DataSource({ 
     transport: { 
      read: 
      { 
       url: "api/dashboard" 
      } 
     }, 
     schema: { 
      **data: function (data) 
      { 
       return [data]; 
      }** 
     } 
    }); 

La mia risposta non era un array, stavo tornando dal server un oggetto di risposta come this:

{"Field1":0,"Field2":0,"Field3":0} 
28

Ho avuto lo stesso errore con un ComboBox che stavo usando come completamento automatico. Nel mio controller, l'istruzione return era

return Json(model.ToDataSourceResult(dataSourceRequest), JsonRequestBehavior.AllowGet) 

che ho cambiato per

return Json(model, JsonRequestBehavior.AllowGet) 

Questo ha fornito la matrice al livello principale, invece di un livello profondo per me.

+1

Nel mio caso sto usando OData e l'ho implementato in questo modo: http://www.whatsinyourlunch.com/odata-kendo-ui-entity-framework-webapi/ - quindi il tipo restituito è IEnumerable o IQueryable. – ElHaix

0

grazie "brittongr" ... che ha funzionato anche per me. ma nel mio caso non è giusto, stavo costruendo un grafico, un grafico necessitava di un array ovviamente, quindi invece di alterare lo schema convertendo i miei dati Json in un array sono appena tornato dalla mia azione una lista con un elemento. Qualcosa di simile qui sotto.

Random rand = new Random(); 

int numIterations = 0; 

numIterations = rand.Next(1, 1200); 

List aux = new List&lt;graphicDataItem&gt;(); 

aux.Add(new graphicDataItem { ColumnTotal = 1200, ColumnActives = numIterations, ColumnInactives = 1200 - numIterations, ColumnApprovedByMembers = 250, ColumnApprovedByAssoc = 300, XAxisData = DateTime.Now.Year }); 

return Json(aux, JsonRequestBehavior.AllowGet); 

ho "graphicDataItem" tipo definito sulla mia cartella Enti, ma è facile da ottenere guardando il modo in cui viene creata un'istanza all'interno del codice.

0

a cambiare per questo, e questo lavoro per me:

@(Html.Kendo().AutoComplete() 
.Name("productAutoComplete") //The name of the autocomplete is mandatory. It specifies the "id" attribute of the widget. 
    .DataTextField("myfield") //Specifies which property of the Product to be used by the autocomplete. 
.DataSource(source => 
{ 
    source.Custom() 
    .Type("aspnetmvc-ajax") 
    .Transport(transport=> 
    { 
     transport.Read("MyAction", "Control"); 
    }) 
    .Schema(schema=>schema.Data("Data").Total("Total")) 

    .ServerFiltering(true); //If true the DataSource will not filter the data on the client. 
}) 

)