JS Object Model  Udostępnij na: Facebook

Autor: Jakub Gutkowski

Opublikowano: 2011-08-22

Podobnie jak z Client OM, tak i w JS OM korzystamy z obiektu ClientContext. Różnica polega tylko na tym, iż jedyny sposób dostania się do niego to odwołanie się do metody get_Current().

JS i nazewnictwo. W przypadku wersji Beta SharePoint 2010 MS pozostawił w skrypcie od JS OM informację o tym, iż JS OM został wygenerowany za pomocą Script# (aplikacji konwertującej kod C# do JavaScript) – źródło: http://bit.ly/gChDZn. Mimo iż ta informacja została usunięta w wersji finalnej, można przypuszczać,  że na tej zasadzie został wygenerowany cały kod JS OM. W szczególności patrząc na nazewnictwo metod wykorzystywane w modelu – na przykład get_Current(), jest to metoda generowana przez kompilator C# dla własności Current { get; }. Nie wspominając już o wykorzystaniu atrybutu ScriptType z klas znajdujących się w Client.dll.

Metoda get_Current() zwraca aktualny kontekst, umożliwiający nam – podobnie jak Client OM – zdefiniowanie własności, które chcemy załadować. W naszym przypadku, zamiast ładować cały obiekt Web, ładujemy jedynie własność Title (próba odwołania się do innej własności po załadowaniu spowoduje wywołanie wyjątku).

Następnie wywołujemy metodę executeQueryAsync ładującą dane asynchronicznie – jest to też jedyna możliwość ładowania danych z poziomu JS OM. Metoda ta przyjmuje dwa delegaty:

  1. metoda, która ma zostać wykonana na poprawnym zakończeniu pobierania danych,
  2. metoda, która zostanie wywołana, jeżeli zostanie zwrócony błąd.

Ze względu na to, że korzystamy z asynchronicznego pobierania danych, niezbędne jest przechowanie obiektu Web w zmiennej globalnej (lub jeżeli będziemy tworzyć elegancki kod JS – w zmiennej obiektowej). Jest to niezbędne, jeżeli będziemy chcieli następnie odwołać się do własności danego obiektu. Co zresztą wykonujemy w metodzie OnSuccess.

Proszę zwrócić uwagę, że po raz kolejny zamiast nazwy własności mamy metodę get_Title().

Na samym końcu czyścimy obiekt web, aby nie zajmował nam zbędnej przestrzeni lub by przy kolejnym wykonaniu zapytania nie posiadał „przypisanych” własności.

Przykład 3: Wyświetl nazwy wszystkich list na witrynie

// server
public void IterateListsSom()
{
    using(SPSite site = new SPSite(SiteUrl))
    using(SPWeb web = site.OpenWeb())
    {
        foreach(SPList list in web.Lists)
        {
            Console.WriteLine("List Title: {0}", list.Title);
        }
    }
}
// client
public void IterateListsCom()
{
    using(ClientContext ctx = new ClientContext(SiteUrl))
    {
        Web web = ctx.Web;
        ListCollection lists = web.Lists;
        ctx.Load(lists);
        ctx.ExecuteQuery();

        foreach(List list in lists)
        {
            Console.WriteLine("List Title: {0}", list.Title);
        }
    }
}
// javascript
var lists = null;
function iterateListsJs() {
    var context = SP.ClientContext.get_current();
    this.lists = context.get_web().get_lists();

    context.load(this.lists);

    context.executeQueryAsync(
            Function.createDelegate(this, this.onIterateListsJsSucceeded),
            Function.createDelegate(this, this.onIterateListsJsFailed));
}

function onIterateListsJsSucceeded() {
    var enumerator = this.lists.getEnumerator();

    while (enumerator.moveNext()) {
        var list = enumerator.get_current();
        alert(list.get_title());
    }

    this.lists = null;
}

function onIterateListsJsFailed() {
    alert('Iterate Lists Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
    this.lists = null;
}

Jak widać w przykładzie, pobieramy listę wszystkich list, które są dostępne na danej witrynie, i zwracamy tytuł każdej z nich. Lista, podobnie jak witryna w SharePoint, posiada reprezentację graficzną, na przykład lista zadań może wyglądać tak:

Listy w SharePoint są domyślnym miejscem składowania danych i aby je dokładniej omówić, należałoby napisać na ten temat obszerny artykuł. Jest to spowodowane zawiłościami modelu dostępowego do list, który – przy wykorzystaniu bez zastanawiania się i zaglądania do wnętrza SharePoint – może spowodować całkowite zawieszenie aplikacji.

To, co nam kod zwróci, możemy znaleźć pod adresem: http://site_url/_layouts/viewlsts.aspx:

Server OM

Po utworzeniu obiektu witryny odwołujemy się do własności Lists zwracającej nam obiekt SPListCollection.

Kolekcje w SharePoint. Żadna kolekcja w SharePoint (przynajmniej z tych mi znanych) nie wykorzystuje generycznego interfejsu ICollection<T>, natomiast zawiera implementację ICollection. Dlatego też w foreach nie możemy wykorzystywać słowa kluczowego var, a musimy określać typ danego obiektu. Kolekcje w SharePoint mają specyficzne nazewnictwo, które składa się z typu obiektu plus suffixCollection. To znaczy, że SPListCollection zwraca nam obiekty SPList, zaś SPWebCollection obiekty SPWeb itd.

Iterując po SPListCollection przygotujemy obiekty SPList odpowiadające danej liście w SharePoint. Posiadając obiekt SPList, zwracamy jej tytuł za pomocą własności Title.

Client OM

Aby załadować kolekcję list, nie musimy ładować obiektu Web, jednak potrzebujemy zmienną web, aby przechować w niej wynik ładowania. Próba odwołania się do web.Title w tym wypadku zakończy się wyjątkiem, zaś odwołanie się do Lists już nie.

Reszta kodu nie różni się od tego z Server OM.

JS OM

Podobnie jak w Client OM, interesuje nas jedynie pobranie listy obiektów List. Aby jednak móc się do tej listy odwołać, musimy utworzyć zmienną globalną, do której będziemy mieli dostęp w metodzie OnSuccess.

Kod konfigurujący to, co należy pobrać, zbytnio nie różni się od tego z poprzedniego przykładu. Różnica jednak jest w metodzie OnSuccess. Zamiast tablicy obiektów List, zostaje nam zwrócona kolekcja obiektów.

Kolekcje w C#. W C# każda kolekcja implementuje interfejs IEnumerable (plus czasami wersję generyczną). IEnumerable ma jedną metodę, zwracającą IEnumerator umożliwiający iterowanie po elementach. Dzięki czemu możliwe jest wykorzystanie wyrażenia foreach, które przez kompilator zamieniane jest na wykorzystanie enumeratora. W JS OM kolekcja zwrócona jest właśnie taką kolekcją, co tylko i wyłącznie potwierdza, że kod zapewne był wygenerowany na podstawie klas C#.

Przez to, że jest to kolekcja, musimy sami zaimplementować to, co w C# daje nam słowo kluczowe foreach. To znaczy pobieramy enumerator, następnie – dopóki istnieje kolejny element (moveNext powoduje zwrócenie true – jeśli istnieje, false – jeśli nie, oraz zapisanie w zmiennej lokalnej enumeratora aktualnego elementu po wykonaniu metody moveNext) – pobieramy go i wykonujemy na nim metodę get_Title zwracającą nazwę listy.

Dla pewności na końcu czyścimy kolekcję list.

Przykład 4: Stwórz listę na witrynie

// server
public void CreateListSom()
{
    using(SPSite site = new SPSite(SiteUrl))
    using(SPWeb web = site.OpenWeb())
    {
        Guid listId = web.Lists.Add(
                        SomListTitle,
                        SomListDesc,
                        SPListTemplateType.GenericList);

        SPList list = web.Lists[listId];

        Console.WriteLine("List name: {0}", list.Title);
        Console.WriteLine("List desc: {0}", list.Description);
        Console.WriteLine("List items: {0}", list.Items.Count);
    }
}

// client
public void CreateListCom()
{
    using(ClientContext ctx = new ClientContext(SiteUrl))
    {
        Web web = ctx.Web;

        ListCreationInformation lci = new ListCreationInformation();
        lci.Title = ComListTitle;
        lci.Description = ComListDesc;
        lci.TemplateType = (int)ListTemplateType.GenericList;

        web.Lists.Add(lci); 

        List list = web.Lists.GetByTitle(ComListTitle);
        ctx.Load(list);
        ctx.ExecuteQuery();

        Console.WriteLine("List name: {0}", list.Title);
        Console.WriteLine("List desc: {0}", list.Description);
        Console.WriteLine("List items: {0}", list.ItemCount);
    }
}
// javascript
var list = null;
function createListJs() {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();

    var listCreationInfo = new SP.ListCreationInformation();
    listCreationInfo.set_title(jsListName);
    listCreationInfo.set_description(jsListDesc);
    listCreationInfo.set_templateType(SP.ListTemplateType.genericList);

    this.list = web.get_lists().add(listCreationInfo);

    context.load(list);  
    context.executeQueryAsync(
            Function.createDelegate(this, this.onCreateListSuccess),
            Function.createDelegate(this, this.onCreateListFailed));
}
function onCreateListSuccess(sender, args) {
    alert("List title: " + this.list.get_title());
    alert("List desc: " + this.list.get_description());
    alert("List items: " + this.list.get_itemCount());
    this.list = null;
}

function onCreateListFailed(sender, args) {
    alert('Create List Request Failed ' + args.get_message() + '\n' + args.get_stackTrace());
    this.list = null;
}

W przykładzie tym tworzymy listę na danej witrynie i nadajemy jej zarówno tytuł, jak i opis. Kod powyżej odpowiada manualnej czynności:

Server OM

W przykładzie wykorzystujemy znaną nam już własność Lists z obiektu SPWeb w celu dodania nowej listy do witryny za pomocą metody Add.

Kolekcje w SharePoint po raz kolejny. Wszystkie akcje dodania danego elementu do SharePoint odbywają się poprzez kolekcje. Przeważnie jest to dostępne poprzez metodę Add zwracającą ID (GUID) dodanego elementu, który następnie jesteśmy w stanie pobrać z SharePoint, odwołując się do jego ID. Czasami jednak zwracany jest nam obiekt – np. SPWebCollection.Add zwróci SPWeb, zaś już SPListCollection.Add zwróci ID listy.

Istnieje wiele przeciążeń metody Add, i ono  jest chyba najbardziej popularne. W celu utworzenia nowej listy podajemy jej tytuł, jej opis oraz typ.

Typy list w SharePoint. W SharePoint dostępnych jest dużo domyślnych typów list, np. szablony list dostępne domyślnie w SharePoint są wypisane tutaj: http://bit.ly/guG8it.

Metoda Add zwraca nam ID świeżo utworzonej listy, które następnie wykorzystujemy w celu pobrania danej listy.

Indeksy w SharePoint. Każda kolekcja i duża liczba obiektów w SharePoint implementuje dostęp do elementów poprzez indeksy. Najczęściej spotykane są indeksy po ID (GUID), nazwie (string) lub też „kolejności” (INT). Najbardziej wydajne jest wykorzystywanie GUID.

Po pobraniu obiektu SPList odwołujemy się do jego trzech własności: (1) tytułu, który poznaliśmy w poprzednim przykładzie, (2) opisu, który ustawiliśmy w trakcie tworzenia listy oraz do (3) liczby elementów na liście – Items zwraca SPListItemCollection, który jest furtką do dostępu do elementów na liście.

Items.Count i ItemCount. W założeniach dwie wartości powinny być równe, jednak tak nie jest. Rozważania, dlaczego tak się dzieje, sięgają trochę bardziej w głąb SharePointa. Powinno nam teraz jednak wystarczyć, że: (1) ItemCount zwraca liczbę elementów na liście, pomijając uprawnienia na elementach, Items.Count nie pomija uprawnień na elementach, (2) ItemCount zwraca snapshot liczby elementów, Items.Count za każdym razem pobiera całą zawartość listy, aby zwrócić liczbę elementów. Różnice są więc znaczące, a pisanie, że najlepszą praktyką jest wykorzystywanie ItemCount, jest błędne i złe oraz wprowadza w błąd programistów. Jeżeli więc gdzieś przeczytacie, że najlepiej jest stosować ItemCount czy też Items.Count, od razu dajcie komentarz mówiący taaa. Jest to naprawdę najgłupszy bestpractice jaki widziałem do SharePointa.

Praca z SPListItemCollection. Najlepszą praktyką jest praca na zmiennej lokalnej, odwoływanie się za każdym razem do list. Items będzie powodowało kolejne zapytania do SharePoint (dosłownie tak się dzieje, SharePoint tego nie cachuje). Jeżeli musicie pracować z listą elementów, przypiszcie ją do zmiennej lokalnej.

Client OM

W Client OM istnieje znacząca różnica w sposobie tworzenia nowej listy. Przede wszystkim, aby stworzyć taką listę musimy utworzyć obiekt ListCreationInformation. Następnie, pracując z obiektem określamy dokładnie, co chcemy utworzyć – nazwę, opis oraz typ listy.

Mając tak przygotowany obiekt, wykonujemy operację dodania go do listy obiektów. Następnie pobieramy listę za pomocą tytułu i określamy, co chcemy załadować z SharePoint (w naszym przypadku obiekt List).

Po określeniu ładowania wykonujemy zapisane operacje, które w kolejności: (1) utworzą listę w SharePoint, (2) zwrócą ją nam; a wszystko to w jednym zapytaniu do SharePoint. Jest to o tyle ważne, że nie prosimy SharePoint o coś dwa razy, bo wystarczy tylko raz.  Jest to więc prawie tak samo super rozwiązanie, jak Future w nHibernate.

Na końcu wyświetlamy informacje na temat tytułu, opisu i liczby elementów na liście. Z tą różnicą, że w Server OM wykorzystaliśmy Items.Count, a tutaj wykorzystujemy ItemCount. Jest to spowodowane tym, iż nie załadowaliśmy informacji o elementach listy, więc nie mamy do nich dostępu. Mamy zaś dostęp do snapshotu informacji o liczbie elementów na liście.

JS OM

Sposób utworzenia listy w JS OM nie różni się od Client OM.

Przykład 5: Dodaj element do listy na witrynie

// server
public void AddListItemSom()
{
    using(SPSite site = new SPSite(SiteUrl))
    using(SPWeb web = site.OpenWeb())
    {
        SPList list = web.Lists[SomListTitle];

        SPListItem item = list.AddItem();
        item["Title"] = "Some title";
        item.Update();
    }
}
        
// client
public void AddListItemCom()
{
    using(ClientContext ctx = new ClientContext(SiteUrl))
    {
        Web web = ctx.Web;

        ListItemCreationInformation lici = new ListItemCreationInformation();
        List list = web.Lists.GetByTitle(ComListTitle);

        ListItem item = list.AddItem(lici);
        item["Title"] = "Some title";
        item.Update();
        ctx.ExecuteQuery();
    }
}
// javascript
function createListItemJs() {
    var context = new SP.ClientContext.get_current();

    var list = context.get_web().get_lists().getByTitle(jsListName);

    var itemCreateInfo = new SP.ListItemCreationInformation();

    var item = list.addItem(itemCreateInfo);
    item.set_item('Title', 'Some Title');
    item.update();

    context.executeQueryAsync(
        Function.createDelegate(this, this.onCreateListItemSuccess),
        Function.createDelegate(this, this.onCreateListItemFailed));
}
function onCreateListItemSuccess(sender, args) {
    alert('ok'); 
}

function onCreateListItemFailed(sender, args) {
    alert('Create List Item Request Failed ' + args.get_message() + '\n' + args.get_stackTrace());
}

W przykładzie tym do wcześniej utworzonej listy dodajemy element. Kod jest równoważny z akcją:

Kończy się ona następującym widokiem:

Dodatkowo w opisie kodu poruszany jest temat pól w SharePoint – tak zwanych kolumn na liście:

Jak i typie danego pola:

Server OM

Po pobraniu listy wykonujemy na niej operację AddItem. Metoda ta wywołuje publiczną metodę Add z kolekcji SPListItemCollection.

Metoda AddItem zwraca nam obiekt SPListItem, który nie jest jeszcze fizycznie dodany do listy. Daje nam to możliwość ustawienia wszystkich jego niezbędnych wartości (w tym wypadku tytułu) i wykonaniu na nim operacji Update, która to dopiero doda element do listy.

Uwaga. Jeżeli pobraliśmy listę elementów przed wykonaniem Update na elemencie, to należy pobrać ją ponownie – w przeciwnym wypadku nasz element nie będzie na niej widoczny.

Obiektem zwracanym przez item[] jest wartość pola SPField (kolumny) lub null. W SharePoint jest dostępnych wiele typów pól, jak chociażby liczba, lookup czy też pole tekstowe wielolinijkowe*.* Wszystkie one są wymienione w enum SPFieldType (http://bit.ly/gZeQcS) i każde z nich dziedziczy po obiekcie SPField. Jako programiści możemy tworzyć również własne pola.

Czasami się zdarza, że po zwróceniu obiektu za pomocą item[] musimy go zrzutować na odpowiedni typ – dla przykładu SPFieldLookupValue. Czasami jednak, jak w wypadku Title, nie jest to wymagane.

Na temat poruszania się, rozszerzania i wykorzystywania SPField, SPFieldCollection oraz SPFieldXXXValue (gdzie XXX to rodzaj pola), a także wykonywania operacji na SPListItem można napisać wiele, gdyż często coś, co wydaje się proste, nie zawsze takie jest. Ważne jest dla nas teraz to, że item[] najpierw pobiera pole SPField, a następnie za jego pomocą wartość pola. To, co jest nam zwracane, to object, a nie określony typ obiektu. Dlatego czasami wymagana jest konwersja na określony typ, aby móc operować na wartości pola.

Client OM

Podobnie jak przy tworzeniu listy, korzystamy z obiektu XxxCreationInformation – jest to zestandaryzowane nazewnictwo w klienckich modelach obiektowych. W naszym przypadku wykorzystujemy teraz ListItemCreationInformation, nie ustawiając żadnych jego parametrów – będą one ustawione na domyślne dla danej listy – tak samo jak jest to wykonywane przez metodę Add na SPListItemCollection w Server OM.

Następnie pobieramy listę za pomocą metody GetByTitle – mamy jeszcze jedynie dostępną metodę GetById, która przyjmuje jako parametr ID listy. Jednak ze względu na uproszczenie przykładów i możliwość ich rozbicia na pomniejsze, nie przechowujemy ID listy, którą utworzyliśmy. Stąd też odwołanie po nazwie.

Kolejnym krokiem jest wykorzystanie własności Items i metody Add przyjmującej jako parametr typ ListItemCreationInformation.

Dopiero po skończeniu wszystkich operacji wykonujemy metodę Update, a następnie wywołujemy żądanie, które utworzy nam element na liście.

JS OM

Kod w tym przypadku dla JS OM nie różni się od kodu dla Client OM.

Przykład 6: Wyświetl wszystkie elementy na danej liście na witrynie

// server
public void IterateListItemsSom()
{
    using(SPSite site = new SPSite(SiteUrl))
    using(SPWeb web = site.OpenWeb())
    {
        SPList list = web.Lists[SomListTitle];

        foreach(SPListItem item in list.Items)
        {
            Console.WriteLine("{0}", item.Title);
        }
    }
}

// client
public void IterateListItemsCom()
{
    using(ClientContext ctx = new ClientContext(SiteUrl))
    {
        Web web = ctx.Web;

        List list = web.Lists.GetByTitle(ComListTitle);

        CamlQuery query = new CamlQuery();

        ListItemCollection items = list.GetItems(query);
        ctx.Load(items);
        ctx.ExecuteQuery();

        foreach(ListItem item in items)
        {
            Console.WriteLine("{0}", item["Title"]);
        }
    }
}
// javascript
var listItems = null;
function iterateListItemsJs() {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();

    var list = web.get_lists().getByTitle(jsListName);

    var camlQuery = new SP.CamlQuery();

    this.listItems = list.getItems(camlQuery);
    context.load(listItems, 'Include(DisplayName)');

    context.executeQueryAsync(
        Function.createDelegate(this, this.onIterateListItemsSuccess),
        Function.createDelegate(this, this.onIterateListItemsFailed));
}

function onIterateListItemsSuccess(sender, args) {
    var listEnumerator = this.listItems.getEnumerator();

    while (listEnumerator.moveNext()) {
        var item = listEnumerator.get_current();

        var title = item.get_displayName();

        alert(title);
    }

    this.listItems = null;
}

function onIterateListItemsFailed(sender, args) {
    alert('Iterate List Items Request Failed ' + args.get_message() + '\n' + args.get_stackTrace());
    this.listItems = null;
}

W przykładzie pobieramy listę wszystkich elementów na danej liście i zwracamy ich tytuł.

Server OM

Po pobraniu obiektu listy wykorzystujemy znaną nam już własność Items w celu zwrócenia wszystkich elementów na liście, po których iterujemy i pobieramy wartość Title. Wywołanie item["Title"] jest równoważne z wykonaniem item.DisplayName.

Client OM

Ze względu na to, iż zarówno model Client, jak i JS OM nie zawierają własności Itemsdla listy, aby więc pobrać listę elementów, niezbędne jest utworzenie zapytania, wykorzystując w SharePoint język zapytań CAML.

Jeżeli nie interesuje nas skomplikowane zapytanie, możemy pójść na skróty i nie tworzyć zapytania, a jedynie obiekt odpowiedzialny za zapytanie – CamlQuery. Taki obiekt przekazujemy do metody GetItems, która zwróci nam kolekcję ListItemCollection. Jednak zanim to nastąpi, musimy poinformować Client OM co chcemy pobrać i wykonać operację pobrania wartości. Dopiero potem możemy iterować po pobranej liście elementów.

JS OM

JS OM niewiele się różni od Client OM. Jedyna różnica polega na tym, że przy określaniu, co ma zostać załadowane, a listę własności ograniczamy do informacji o display name. Bardzo przydatny feature, który umożliwia ładowanie jedynie określonych własności, ogranicza rozmiar ściąganych danych.

Przykład 7: Usuń listę

// server
public void DeleteListSom()
{
    using(SPSite site = new SPSite(SiteUrl))
    using(SPWeb web = site.OpenWeb())
    {
        SPList list = web.Lists[SomListTitle];
        list.Delete();
    }
}

// client
public void DeleteListCom()
{
    using(ClientContext ctx = new ClientContext(SiteUrl))
    {
        Web web = ctx.Web;

        List list = web.Lists.GetByTitle(ComListTitle);
        list.DeleteObject();
        ctx.ExecuteQuery();
    }
}
// javascript
function deleteListJs() {
    var context = new SP.ClientContext.get_current();

    var list = context.get_web().get_lists().getByTitle(jsListName);
    list.deleteObject();

    context.executeQueryAsync(
        Function.createDelegate(this, this.onDeleteListSuccess),
        Function.createDelegate(this, this.onDeleteListFailed));
}
function onDeleteListSuccess(sender, args) {
    alert('ok');
}

function onDeleteListFailed(sender, args) {
    alert('Delete List Request Failed ' + args.get_message() + '\n' + args.get_stackTrace());
}

W przykładzie usuwamy wcześniej utworzoną listę wraz ze wszystkimi elementami, które się na niej znajdują. Kod jest równoważny z wykonaniem następującej czynności:

Server OM

Kod jest bardzo prosty –  po pobraniu listy wykonujemy na niej operację Delete, która usuwa listę i w zależności od tego, czy kosz na stronie jest włączony, czy wyłączony, usunięta lista jest wstawiana do kosza lub nie.

Client OM

Podobnie jak w przypadku Server OM, najpierw rejestrujemy akcję pobrania listy, na której wykonujemy operację DeleteObject – jest to typowa metoda dla Client i JS OM, jeżeli chcemy coś usunąć, wykorzystując wymienione modele obiektowe, to musimy wywoływać właśnie tę metodę. Metoda Delete nie istnieje.

Po zarejestrowaniu akcji wykonujemy żądanie ich wykonania, co powoduje usunięcie listy z witryny.

JS OM

Kod dla JS OM nie różni się od kodu od Client OM.

Podsumowanie

Dość dużo informacji zostało podanych, zrobiliśmy też pobieżny przegląd dostępnych modeli obiektowych, koncentrując się na bibliotekach, a nie na dostępnych metodach odpytywania SharePointa o dane.

Powinniśmy być w stanie rozróżnić i powiedzieć, czym się różnią dane modele obiektowe oraz jakie korzyści płyną z wybrania danej opcji. Powinniśmy też wiedzieć, gdzie można wykorzystać dany model obiektowy (może to się wydawać zabawne, ale pierwsza rzecz, jaką zrobiłem, to chciałem ze swojej aplikacji za pomocą JavaScript OM odwołać się do SharePointa...).

Na przykładach poznaliśmy klasy, z którymi będziemy tak naprawdę współpracować 70–80% czasu w trakcie tworzenia aplikacji. Pewne rzeczy nie zostały wyjaśnione, takie jak LINQ czy też dlaczego używamy using w modelu obiektowym serwera. Ale o tych sprawach będzie mowa w następnych częściach artykułów.

Dowiedzieliśmy się także kilku ciekawostek – jaka jest podstawowa różnica między ItemCount a Items.Count, dlaczego warto odwoływać się po GUID czy też w jaki sposób generowany jest model obiektowy dla javascript.

No i napisaliśmy duży fragment naprawdę niezłego kodu!

Trudno to wszystko zapamiętać, dlatego może warto po prostu wrócić później do fragmentów, które umknęły naszym neuronom i w spokoju powtórzyć materiał.

Załącznik

Dla przypomnienia – tabelki prezentują większość obiektów, o których była mowa w artykule, oraz metod wykorzystywanych w przykładach.

Server OM Client OM JS OM
SPSite Site Site
SPWeb Web Web
SPList List List
SPListCollection ListCollection ListCollection
SPListItem ListItem ListItem
SPListItemCollection ListItemCollection ListItemCollection
SPField Field Field
SPFieldCollection FieldCollection FieldCollection
Server OM Client OM JS OM
SPSite(URL) ClientContext(URL) SP.ClientContext.get_current()
site.OpenWeb() ctx.Web ctx.get_web()
web.Lists web.Lists web.get_lists()
web.Lists[TITLE] web.Lists.GetByTitle(TITLE) web.get_lists().getByTitle(TITLE)
list.Items list.GetItems(CAML_QUERY) list.getItems(CAML_QUERY)
obj.Delete() obj.DeleteObject() obj.deleteObject()
obj.Update() obj.Update() obj.update()
item[TITLE] item[TITLE] Item.get_title()
item[TITLE] =VAL item[TITLE] = VAL Item.set_title(VAL)