2015-08-06 9 views
9

mam następujące (uproszczony) schematu SimpleSchema w moim Meteor 1.1.0.2 app:Pull wpisu z tablicy poprzez Meteor

Tickers.attachSchema(
    new SimpleSchema({ 
     entries: { 
      type: [TickerEntries], 
      defaultValue: [], 
      optional: true 
     } 
    }) 
); 

TickerEntries = new SimpleSchema({ 
    id: { 
     type: String, 
     autoform: { 
      type: "hidden", 
      label: false, 
      readonly: true 
     }, 
     optional: true, 
     autoValue: function() { 
      if (!this.isSet) { 
       return new Mongo.Collection.ObjectID()._str; 
      } 
     } 
    }, 
    text: { 
     type: String, 
     label: 'Text' 
    } 
}; 

w bazie mam następujące wpisy:

{ 
    "_id" : "ZcEvq9viGQ3uQ3QnT", 
    "entries" : [ 
     { 
      "text" : "a", 
      "id" : "fc29774dadd7b37ee0dc5e3e" 
     }, 
     { 
      "text" : "b", 
      "id" : "8171c4dbcc71052a8c6a38fb" 
     } 
    ] 
} 

Chciałbym usunąć jeden wpis z tablicy wpisów określonej przez identyfikator.

Gdybym wykonać następujące polecenie w Meteor-MongoDB-shell to działa bez problemów:

db.Tickers.update({_id:"3TKgHKkGnzgfwqYHY"}, {"$pull":{"entries": {"id":"8171c4dbcc71052a8c6a38fb"}}}) 

Ale problemem jest to, że jeśli mam zamiar zrobić to samo z poziomu Meteor to robi nie działa. Oto mój kod:

Tickers.update({id: '3TKgHKkGnzgfwqYHY'}, {$pull: {'entries': {'id': '8171c4dbcc71052a8c6a38fb'}}}); 

Ja również próbowałem następujące:

Tickers.update('3TKgHKkGnzgfwqYHY', {$pull: {'entries': {'id': '8171c4dbcc71052a8c6a38fb'}}}); 

Żadne z tych poleceń dać mi błąd, ale nie usunąć wszystko z mojego dokumentu.

Czy to możliwe, że polecenie $pull nie jest obsługiwane poprawnie lub czy gdzieś popełniłem błąd?

Z góry dziękuję!

EDYCJA: Znalazłem problem, którego nie można zobaczyć w moim opisie, ponieważ uprościłem mój schemat. W mojej aplikacji jest dodatkowy atrybut timestamp w TickerEntries:

TickerEntries = new SimpleSchema({ 
    id: { 
     type: String, 
     optional: true, 
     autoValue: function() { 
      if (!this.isSet) { 
       return new Mongo.Collection.ObjectID()._str; 
      } 
     } 
    }, 
    timestamp: { 
     type: Date, 
     label: 'Minute', 
     optional: true, 
     autoValue: function() { 
      if (!this.isSet) { // this check here is necessary! 
       return new Date(); 
      } 
     } 
    }, 
    text: { 
     type: String, 
     label: 'Text' 
    } 
}); 

Dzięki wskazówce od Kyll, Utworzyłem Meteorpad i okazało się, że funkcja autovalue jest przyczyną problemów.

Mam teraz zmienił funkcję na następujący kod:

autoValue: function() { 
    if (!this.isSet && this.operator !== "$pull") { // this check here is necessary! 
     return new Date(); 
    } 
} 

A teraz pracuje. Wydaje się, że zwracanie wartości auto wartości w przypadku ciągnięcia elementu/obiektu powoduje anulowanie operacji przeciągania, ponieważ wartość nie jest ustawiona na zwróconą wartość (tak, że atrybut znacznika czasu zachowuje starą wartość, ale nie jest ciągnięty).

Oto według Meteorpad przetestować go (po prostu skomentuj czek dla operatora w funkcji autovalue): http://meteorpad.com/pad/LLC3qeph66pAEFsrB/Leaderboard

Dziękuję wszystkim za pomoc, wszystkie Twoje posty były bardzo pomocne dla mnie!

+1

Proponuję sporządzania się w [MeteorPad] (http://meteorpad.com/), aby pokazać swój problem (tworzenie DB, dodać schematów, wypełnić go, spróbuj usunąć i pokazać niepowodzenie). Kolejna kwestia: czy usunięcie załączonych schematów zmienia cokolwiek w twoim problemie? Jeśli nie, możesz całkowicie usunąć je z pytania, ponieważ tak naprawdę nie wiem, czy schematy mają znaczenie, czy też nie. Na koniec gratuluję formatu i czystości Twojego posta! Jeśli dodasz znacznik [tag: javascript] do pytania, automatycznie doda on kolory do kodu. –

+1

Sugeruję, że popełniłeś błąd lub masz błąd konfiguracji lub gdzieś się kłócisz. Przesłałem odpowiedź, która pokazuje w pełni sprawną sprawę. Pomoże to zawęzić wszelkie problemy, które mogą wystąpić, jeśli coś innego zakłóca oczekiwane zachowanie '$ pull'. –

+1

Naprawiono nasze problemy - autovalue blokowało $ pull. Dziękuję za dokładne pytanie i odpowiedź @ reini122. –

Odpowiedz

5

W przypadku podstawowego zastosowania meteorów nazywam to "piętrowym".Jeśli tworzysz nowy projekt i po prostu określić kolekcję, a następnie operator $pull działa zgodnie z oczekiwaniami:

konsoli:

meteor create tickets 
cd tickets 
meteor run 

Następnie otwórz konsolę i wstawić swoje dane:

meteor mongo 

> db.tickets.insert(data) // exactly your data in the question 

Następnie wystarczy wydrukować podstawowy kod i szablon:

tickers.js

Tickers = new Meteor.Collection("tickers"); 

if (Meteor.isClient) { 

    Template.body.helpers({ 
    "tickers": function() { 
     return Tickers.find({}); 
    } 
    }); 

} 

if (Meteor.isServer) { 
    Meteor.startup(function() { 
    // code to run on server at startup 
    }); 
} 

tickers.html

<head> 
    <title>tickers</title> 
</head> 

<body> 
    <h1>Welcome to Meteor!</h1> 

    <ul> 
    {{#each tickers}} 
     {{> ticker}} 
    {{/each}} 
    </ul> 

</body> 

<template name="ticker"> 
    <li> 
    {{_id}} 
    <ul> 
     {{#each entries}} 
     {{> entry }} 
     {{/each}} 
    </ul> 
    </li> 
</template> 

<template name="entry"> 
    <li>{{ id }} - {{text}}</li> 
</template> 

Wniosek powinien zostać uruchomiony w porządku, więc w konsoli przeglądarki zrobić .update() (wgniatany do odczytu):

Tickers.update(
    { "_id": "ZcEvq9viGQ3uQ3QnT" }, 
    { "$pull": { "entries": { "id": "fc29774dadd7b37ee0dc5e3e" } }} 
) 

Element zostanie usunięty z wpisów, a strona zostanie odświeżona bez elementu. Więc wszystko zniknęło, zgodnie z oczekiwaniami.

Nawet dodanie pakietów SimpleSchema i Collection2, nie ma znaczenia tutaj:

meteor add aldeed:simple-schema 
meteor add aldeed:collection2 

tickers.js

Tickers = new Meteor.Collection("tickers"); 

TickerEntries = new SimpleSchema({ 
    "id": { 
    type: String, 
    optional: true, 
    autoValue: function() { 
     if (!this.isSet) { 
     return new Mongo.Collection.ObjectID()._str 
     } 
    } 
    }, 
    "text": { 
    type: String 
    } 
}); 

Tickers.attachSchema(
    new SimpleSchema({ 
    entries: { type: [TickerEntries] } 
    }) 
); 


if (Meteor.isClient) { 

    Template.body.helpers({ 
    "tickers": function() { 
     return Tickers.find({}); 
    } 
    }); 

} 

if (Meteor.isServer) { 
    Meteor.startup(function() { 
    // code to run on server at startup 
    }); 
} 

Ponownie zainicjować dane i uruchomić tego samego polecenia w konsoli przeglądarki i wszystko pozostaje takie samo.

Sprawdź to lub wszelkie błędy typowania we własnych działaniach lub inne różnice, aby dowiedzieć się, dlaczego to nie działa.

Sugerowałbym to zdecydowanie, ponieważ "rozpoczęcie od nowa" w ten sposób pokazuje oczekiwane zachowanie, a jeśli widzisz inne zachowanie, prawdopodobnie jest to problem z inną wtyczką, którą zainstalowałeś.

Ale ogólnie to działa.

+0

Dzięki za ten czysty i szeroki przykład! :-) – reini122

+0

@ reini122 Naprawdę mam nadzieję, że jest tu coś, co "rozwiązało" problem, ale poza tym moim zamiarem było pokazanie, na co reagują podstawowe pakiety, które mógłbym odpowiedzieć na twoje pytanie. Jeśli w przeciwnym razie znajdziesz konflikt, prosimy o powiadomienie mnie o błędzie. Komentarze StackOverflow można później wyczyścić, ale mam osobisty interes, jeśli istnieje konflikt pakietów, który powoduje, że problem wymaga interwencji w celu rozwiązania problemu. –

+0

Tak, już rozwiązałem problem i zredagowałem oryginalne pytanie za pomocą rozwiązania. Mam nadzieję, że jest to jasne. Dodałem także Meteorpada, aby zasymulować problem, ale jest to definitywny problem SimpleSchema, ponieważ autovalue zatrzymuje działanie operatora wyciągania w przypadku pola sygnatury czasowej, ale podobny kod w polu ID nie łamie się funkcjonalność. – reini122

0

Wystarczy wspomnieć, jeśli ktoś szuka odpowiedzi.

Jeśli usein SimpleSchema, masz dwie opcje: pole tablicy powinny być oznaczone jako opcjonalne

arr: { 
type:Array, 
optional:true 
} 

lub użyj getAutoValues: false w update-zapytania.

Coll.update({}, {$pull: {arr: ''}}, {getAutoValues: false}); 
Powiązane problemy