예제 #1
0
        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);
        }
예제 #3
0
 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);
        }
예제 #6
0
 public SimpleViewModel()
 {
     FullName =
         new ComputedObservable<string>(
             () =>
                 string.Format("{0}{2} {1}",
                     FirstName.Value,
                     LastName.Value,
                     HasMiddleName ? (" " + MiddleName.Value) : ""));
 }
예제 #7
0
 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();
 }
예제 #8
0
 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);
 }
예제 #9
0
 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);
 }
예제 #10
0
 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);
 }
예제 #11
0
 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);
        }
예제 #13
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);
 }
예제 #16
0
        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();
        }
예제 #17
0
        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();
        }
예제 #18
0
 public void TestImplicitCast()
 {
     var observable = new ComputedObservable<string>(() => "expected");
     string actual = observable;
     Assert.AreEqual("expected", actual);
 }
예제 #19
0
 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;
                    });
            });
        }
예제 #21
0
 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);
 }
예제 #22
0
 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);
 }
예제 #23
0
        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";
        }
예제 #24
0
 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);
 }
예제 #25
0
 public void TestWriteCallback()
 {
     string wroteValue = null;
     var observable = new ComputedObservable<string>(() => "expected", value => wroteValue = value);
     observable.Value = "expectedVal";
     Assert.AreEqual("expectedVal", wroteValue);
 }
예제 #26
0
 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]);
 }
예제 #27
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);
 }
예제 #28
0
 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);
 }
예제 #29
0
 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);
 }
예제 #30
0
 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();
                }
            );
        }
예제 #32
0
 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);
 }