public AppModel() { FirstName = Knockout.Observable <string>(String.Empty); LastName = Knockout.Observable <string>(String.Empty); FullName = Knockout.Computed <string>(ComputeFullName); }
public PersonViewModel() { this.FirstName = Knockout.Observable("Matthew"); this.LastName = Knockout.Observable("Leibowitz"); this.FullName = Knockout.Computed(() => this.FirstName.Value + " " + this.LastName.Value); // AND, there is way to perform the updates to the computed object //var options = new DependentObservableOptions<string>(); //options.GetValueFunction = () => self.FirstName.Value + " " + self.LastName.Value; //options.SetValueFunction = s => //{ // s = s.Trim(); // var index = s.IndexOf(" "); // if (index == -1) // { // self.FirstName.Value = s; // self.LastName.Value = string.Empty; // } // else // { // self.FirstName.Value = s.Substring(0, index); // self.LastName.Value = s.Substring(index + 1, s.Length); // } //}; //this.FullName = Knockout.Computed(options); }
public void TestDontDependWithPeek() { var property = new ObservableProperty<int>(5); var computed = new ComputedObservable<int>(() => property.Peek() + 1); Assert.AreEqual(6, computed.Value); property.Value = 10; Assert.AreEqual(6, computed.Value); }
public void TestAccessSingleValue() { var property = new ObservableList<int>(5, 2, 7); var computed = new ComputedObservable<int>(() => property[2] + 1); Assert.AreEqual(8, computed.Value); property[2] = 10; Assert.AreEqual(11, computed.Value); }
public ClickCounterViewModel() { var self = this; this.NumberOfClicks = Knockout.Observable(0); this.RegisterClick = () => self.NumberOfClicks.Value = self.NumberOfClicks.Value + 1; this.ResetClicks = () => self.NumberOfClicks.Value = 0; this.HasClickedTooManyTimes = Knockout.Computed(() => self.NumberOfClicks.Value >= 3); }
public SimpleViewModel() { FullName = new ComputedObservable<string>( () => string.Format("{0}{2} {1}", FirstName.Value, LastName.Value, HasMiddleName ? (" " + MiddleName.Value) : "")); }
public ViewModel() { // FoodTypeCounts = // new ComputedObservable<Dictionary<FoodChoice, int>>( // () => // Guests.GroupBy(guest => guest.FoodChoice.Value, // (choice, guests) => new {choice, count = guests.Count()}) // .ToDictionary(arg => arg.choice, arg => arg.count)); AttendingGuests = new ComputedObservable<int>(() => Guests.Count(guest => guest.Attending)); SelectedGuest.Value = Guests.First(); }
public void TestCachedEvaluation() { int timesEvaluated = 0; var observable = new ComputedObservable<string>(() => { timesEvaluated++; return "expected"; }); Assert.AreEqual("expected", observable.Value); Assert.AreEqual("expected", observable.Value); Assert.AreEqual(1, timesEvaluated); }
public SelectedListViewModel() { Friends = Observe.List(new Friend("jo"), new Friend("Jason"), new Friend("Rachael"), new Friend("Nathan"), new Friend("Bob")); SelectedFriend = new ObservableProperty<Friend>(); SelectedFriendName = new ComputedObservable<string>( () => SelectedFriend.Value == null ? string.Empty : SelectedFriend.Value.Name.Value, value => SelectedFriend.Value.Name.Value = value); }
public void TestDeferEvaluation() { int timesEvaluated = 0; var computed = new ComputedObservable<int>(() => { timesEvaluated++; return 123; }, true); Assert.AreEqual(0, timesEvaluated); Assert.AreEqual(123, computed.Value); Assert.AreEqual(1, timesEvaluated); }
public void View(ObservableProperty<Guest> selectedGuest) { if (_guest != null) throw new InvalidOperationException("guest already setup"); _guest = selectedGuest; _name = Observe.TwoWayComputed(() => _guest.Value.Name); _attending = Observe.TwoWayComputed(() => _guest.Value.Attending); _invited = Observe.TwoWayComputed(() => _guest.Value.InvitedDate); _foodChoice = Observe.TwoWayComputed(() => _guest.Value.FoodChoice); _name.BindText(nameTextBox); _attending.BindCheckBox(attendingCheckBox); _invited.BindDate(invitedDateCalendar); _foodChoice.BindSelectedComboBox(foodTypeComboBox); }
public void TestEnumAddsDependancy() { var list = new ObservableList<int>(1, 2, 3, 4, 5, 6); var computed = new ComputedObservable<double[]>(() => list.Select(i => Math.Pow(i, 2)).ToArray()) { Name = "ComputedVal" }; CollectionAssert.AreEquivalent(new[] {1.0, 4.0, 9.0, 16.0, 25.0, 36.0}, computed.Value); Assert.AreEqual(1, computed.DependencyCount); list[1] = 10; CollectionAssert.AreEquivalent(new[] {1.0, 100.0, 9.0, 16.0, 25.0, 36.0}, computed.Value); list.Add(100); CollectionAssert.Contains(computed.Value, 10000.0); }
public void TestEvaluateAfterDisposed() { int timesEvaluated = 0; var underlyingProperty = new ObservableProperty<int>(1); var computed = new ComputedObservable<int>(() => { timesEvaluated++; return underlyingProperty.Value; }); Assert.AreEqual(1, timesEvaluated); computed.Dispose(); underlyingProperty.Value = 2; Assert.AreEqual(1, timesEvaluated); Assert.AreEqual(1, computed.Value); Assert.AreEqual(0, computed.DependencyCount); }
public void TestIterateDependancyCount() { int timesComputed = 0; var list = new ObservableList<int>(1, 2, 3, 4, 5, 6); var computed = new ComputedObservable<double>(() => { timesComputed++; double agrigateVal = 0; for (int i = 0; i < list.Count; i++) { agrigateVal += list[i]; } return agrigateVal; }); Assert.AreEqual(21, computed.Value); Assert.AreEqual(1, timesComputed); //should depend on the array and all the indexes in it Assert.AreEqual(7, computed.DependencyCount); }
public void TestComputeSubscriptionOnListOfObservables() { int timesComputed = 0; var list = ObservableList.New(5, 6, 7); list.Name = "List"; var computed = new ComputedObservable<int>(() => { timesComputed++; return list[2].Value + 1; }) {Name = "ComputedVal"}; Assert.AreEqual(8, computed.Value); Assert.AreEqual(1, timesComputed); list[0].Value = 1; Assert.AreEqual(1, timesComputed); list[2].Value = 3; Assert.AreEqual(4, computed.Value); Assert.AreEqual(2, timesComputed); list[1] = new ObservableProperty<int>(10); Assert.AreEqual(2, timesComputed); list[2] = new ObservableProperty<int>(10); Assert.AreEqual(3, timesComputed); Assert.AreEqual(11, computed.Value); }
public CellarApplication() { _pages = Knockout.Observable <int>(0); _pageIndex = Knockout.Observable <int>(0); Wines = Knockout.Observable <IEnumerable <Wine> >(); SelectedWine = Knockout.Observable <Wine>(); CanGoPrevious = Knockout.Computed <bool>(ComputeCanGoPrevious); CanGoNext = Knockout.Computed <bool>(ComputeCanGoNext); ShowSelection = Knockout.Computed <bool>(ComputeShowSelection); Next = delegate() { NextCommand(); }; Previous = delegate() { PreviousCommand(); }; Select = delegate(Wine wine) { SelectCommand(wine); }; LoadWines(); }
public CellarApplication() { _pages = Knockout.Observable<int>(0); _pageIndex = Knockout.Observable<int>(0); Wines = Knockout.Observable<IEnumerable<Wine>>(); SelectedWine = Knockout.Observable<Wine>(); CanGoPrevious = Knockout.Computed<bool>(ComputeCanGoPrevious); CanGoNext = Knockout.Computed<bool>(ComputeCanGoNext); ShowSelection = Knockout.Computed<bool>(ComputeShowSelection); Next = delegate() { NextCommand(); }; Previous = delegate() { PreviousCommand(); }; Select = delegate(Wine wine) { SelectCommand(wine); }; LoadWines(); }
public void TestImplicitCast() { var observable = new ComputedObservable<string>(() => "expected"); string actual = observable; Assert.AreEqual("expected", actual); }
public void TestPeekComputed() { var underlyingProperty = new ObservableProperty<int>(1); var computed1 = new ComputedObservable<int>(() => 1 + underlyingProperty); var computed2 = new ComputedObservable<int>(() => 1 + computed1.Peek()); Assert.AreEqual(3, computed2.Value); Assert.AreEqual(0, computed2.DependencyCount); underlyingProperty.Value = 11; Assert.AreEqual(3, computed2.Value); }
public TwitterViewModel(List<TweetGroup> lists, string selectedList) { var self = this; this.SavedLists = Knockout.ObservableArray(lists); this.EditingList = new TweetGroup( name: Knockout.Observable(selectedList), userNames: Knockout.ObservableArray<string>() ); this.UserNameToAdd = Knockout.Observable(""); this.CurrentTweets = Knockout.ObservableArray(new object[0]); this.FindSavedList = name => KnockoutUtils.ArrayFirst(self.SavedLists.Value, grp => grp.Name.Value == name, self); this.AddUser = () => { if (self.UserNameToAdd.Value != null && self.UserNameToAddIsValid.Value) { self.EditingList.UserNames.Push(self.UserNameToAdd.Value); self.UserNameToAdd.Value = ""; } }; this.RemoveUser = userName => self.EditingList.UserNames.Remove(userName); this.SaveChanges = new Action(OnSaveChanges); this.DeleteList = () => { var nameToDelete = self.EditingList.Name.Value; var savedListsExceptOneToDelete = self.SavedLists.Value.Filter(grp => grp.Name.Value != nameToDelete); self.EditingList.Name.Value = savedListsExceptOneToDelete.Length == 0 ? null : savedListsExceptOneToDelete[0].Name.Value; self.SavedLists.Value = savedListsExceptOneToDelete; }; Knockout.Computed(() => { // Observe viewModel.editingList.name(), so when it changes // (i.e., user selects a different list) we know to copy the // saved list into the editing list var savedList = self.FindSavedList(self.EditingList.Name.Value); if (savedList != null) { var userNamesCopy = savedList.UserNames.Slice(0); self.EditingList.UserNames.Value = userNamesCopy; } else { self.EditingList.UserNames.Value = new string[0]; } }); this.HasUnsavedChanges = Knockout.Computed(() => { if (self.EditingList.Name.Value == null) { return self.EditingList.UserNames.Value.Length > 0; } var savedData = self.FindSavedList(self.EditingList.Name.Value).UserNames; var editingData = self.EditingList.UserNames.Value; return savedData.Value.Join("|") != editingData.Join("|"); }); this.UserNameToAddIsValid = Knockout.Computed(() => { var pattern = @"^\s*[a-zA-Z0-9_]{1,15}\s*$"; return self.UserNameToAdd.Value == "" || self.UserNameToAdd.Value.Match(new Regex(pattern, "g")) != null; }); this.CanAddUserName = Knockout.Computed(() => { return self.UserNameToAddIsValid.Value && self.UserNameToAdd.Value != ""; }); // The active user tweets are (asynchronously) computed from editingList.userNames Knockout.Computed(() => { TwitterApi.GetTweetsForUsers<object[]>( self.EditingList.UserNames.Value, result => { self.CurrentTweets.Value = result; }); }); }
public void TestPreventRecursionOnSetDependency() { int timesEvaluated = 0; var underlyingProperty = new ObservableProperty<int>(1); var computed = new ComputedObservable<int>(() => { timesEvaluated++; underlyingProperty.Value = (underlyingProperty.Value + 1); return 1; }); Assert.AreEqual(1, timesEvaluated); }
public void TestPreventSubscribeViewChangeNotification() { var underlyingProperty = new ObservableProperty<int>(1); var independentProperty = new ObservableProperty<int>(1); var computed = new ComputedObservable<int>(() => underlyingProperty.Value); Assert.AreEqual(1, computed.DependencyCount); computed.Subscribe(value => { var tmp = independentProperty.Value; }, "test"); underlyingProperty.Value = 2; Assert.AreEqual(1, computed.DependencyCount); computed.Subscribe(value => { var tmp = independentProperty.Value; }, ObservableProperty.BEFORE_VALUE_CHANGED_EVENT, "test"); underlyingProperty.Value = 3; Assert.AreEqual(1, computed.DependencyCount); }
public void TestUnsubscribeOnEachChange() { var propertyA = new ObservableProperty<string>("A"); var propertyB = new ObservableProperty<string>("B"); string propertyToUse = "A"; int timesEvaluated = 0; var computed = new ComputedObservable<string>(() => { timesEvaluated++; return propertyToUse == "A" ? propertyA.Value : propertyB.Value; }); Assert.AreEqual("A", computed.Value); Assert.AreEqual(1, timesEvaluated); // Changing an unrelated observable doesn't trigger evaluation propertyB.Value = "B2"; Assert.AreEqual(1, timesEvaluated); // Switch to other observable propertyToUse = "B"; propertyA.Value = "A2"; Assert.AreEqual("B2", computed.Value); Assert.AreEqual(2, timesEvaluated); // Now changing the first observable doesn't trigger evaluation Assert.AreEqual(2, timesEvaluated); propertyA.Value = "A3"; }
public void TestUpdateWhenDependencyChanges() { var property = new ObservableProperty<int>(5); var computed = new ComputedObservable<int>(() => property.Value + 1); Assert.AreEqual(6, computed.Value); property.Value = 10; Assert.AreEqual(11, computed.Value); }
public void TestWriteCallback() { string wroteValue = null; var observable = new ComputedObservable<string>(() => "expected", value => wroteValue = value); observable.Value = "expectedVal"; Assert.AreEqual("expectedVal", wroteValue); }
public void TestSingleUpdateOnMultipleCalls() { var property = new ObservableProperty<int>(2); var computed = new ComputedObservable<int>(() => property + property); Assert.AreEqual(1, computed.DependencyCount); List<int> notifiedValues = new List<int>(); computed.Subscribe(value => notifiedValues.Add(value), "test"); Assert.AreEqual(4, computed.Value); property.Value = 4; Assert.AreEqual(1, notifiedValues.Count); Assert.AreEqual(8, notifiedValues[0]); }
public void TestSubscribeInvokesEvalOnDefer() { var underlyingProperty = new ObservableProperty<int>(1); var computed = new ComputedObservable<int>(() => underlyingProperty.Value, true); var result = new ObservableProperty<int>(); Assert.AreEqual(0, computed.DependencyCount); computed.Subscribe(value => result.Value = value, "test"); Assert.AreEqual(1, computed.DependencyCount); Assert.AreEqual(0, result.Value); underlyingProperty.Value = 42; Assert.AreEqual(42, result.Value); }
public void TestWriteFail() { var observable = new ComputedObservable<string>(() => "expected"); bool thrown = false; try { observable.Value = "fail"; Assert.Fail(); } catch (NotSupportedException e) { thrown = true; } Assert.IsTrue(thrown); }
public void TestSingleUpdateOnChain() { int timesEvaluated = 0; var underlyingPropertyLeft = new ObservableProperty<int>(1) {Name = "Left"}; var underlyingPropertyRight = new ObservableProperty<int>(1) {Name = "Right"}; var computed1 = new ComputedObservable<int>(() => underlyingPropertyRight + underlyingPropertyLeft) { Name = "Compute1" }; var computed2 = new ComputedObservable<int>(() => { timesEvaluated++; return underlyingPropertyLeft + computed1 + underlyingPropertyRight; }) { Name = "Compute2" }; Assert.AreEqual(1, timesEvaluated); Assert.AreEqual(4, computed2); underlyingPropertyLeft.Value = 2; Assert.AreEqual(6, computed2); Assert.AreEqual(2, timesEvaluated); underlyingPropertyRight.Value = 2; Assert.AreEqual(8, computed2); Assert.AreEqual(3, timesEvaluated); }
public void TestReadValue() { var observable = new ComputedObservable<string>(() => "expected"); Assert.AreEqual("expected", observable.Value); }
public AnimatedTransitionsViewModel() { var self = this; Planets = Knockout.ObservableArray(new[]{ new Planet( name: "Mercury", type: "rock"), new Planet( name: "Venus", type: "rock"), new Planet( name: "Earth", type: "rock"), new Planet( name: "Mars", type: "rock"), new Planet( name: "Jupiter", type: "gasgiant"), new Planet( name: "Saturn", type: "gasgiant"), new Planet( name: "Uranus", type: "gasgiant"), new Planet( name: "Neptune", type: "gasgiant"), new Planet( name: "Pluto", type: "rock") }); TypeToShow = Knockout.Observable("all"); DisplayAdvancedOptions = Knockout.Observable(false); AddPlanet = type => self.Planets.Push(new Planet("New planet", type)); PlanetsToShow = Knockout.Computed(() => { // Represents a filtered list of planets // i.e., only those matching the "typeToShow" condition var desiredType = self.TypeToShow.Value; if (desiredType == "all") return self.Planets.Value; return KnockoutUtils.ArrayFilter(self.Planets.Value, planet => planet.Type == desiredType); }); // Animation callbacks for the planets list ShowPlanetElement = elem => { if (elem.NodeType == ElementType.Element) jQuery.FromElement(elem).Hide().SlideDown(); }; HidePlanetElement = elem => { if (elem.NodeType == ElementType.Element) jQuery.FromElement(elem).SlideUp(EffectDuration.Slow, () => jQuery.FromElement(elem).Remove()); }; // Here's a custom Knockout binding that makes elements // shown/hidden via jQuery's fadeIn()/fadeOut() methods //Could be stored in a separate utility library Knockout.BindingHandlers["fadeVisible"] = new InlineBindingHandler<Observable<bool>>( init: (element, valueAccessor, allBindingsAccessor, model) => { // Initially set the element to be instantly visible/hidden // depending on the value var value = valueAccessor.Invoke(); // Use "unwrapObservable" so we can handle values that may // or may not be observable jQuery.FromElement(element).Toggle(KnockoutUtils.UnwrapObservable(value)); }, update: (element, valueAccessor, allBindingsAccessor, model) => { // Whenever the value subsequently changes, slowly fade the // element in or out var value = valueAccessor.Invoke(); if (KnockoutUtils.UnwrapObservable(value)) jQuery.FromElement(element).FadeIn(); else jQuery.FromElement(element).FadeOut(); } ); }
public void TestSubscriptionCounts() { var underlyingPropertyLeft = new ObservableProperty<int>(1) {Name = "Left"}; var underlyingPropertyRight = new ObservableProperty<int>(1) {Name = "Right"}; var simpleComputed = new ComputedObservable<int>(() => underlyingPropertyLeft + 5, true); var layerdComputed = new ComputedObservable<int>(() => simpleComputed + underlyingPropertyRight); Assert.AreEqual(simpleComputed.DependencyCount, 1); Assert.AreEqual(layerdComputed.DependencyCount, 2); }