[JS] AngularJS Tutorial 4

Step_04_篇

第四篇的教學,算是加強之前的觀念。重點 Model 與 View 的綁定關係。最後順便實做一下 ASP.NET PartialView 與 Angular 。

主頁面只做產生畫面及載入相關 css 的動作,InitDialog 則為註冊共用 controller 給 Partial,而過瀘器的部份如果有練習過前幾章節,應該是可以快速上手。

@section scripts{
 @Styles.Render("~/Content/themes/base/css")

 <script src="~/Scripts/angular.js"></script>
 <script src="~/Scripts/MyLibs/Tutorial_04/A001.js"></script>
 @Scripts.Render("~/bundles/jqueryui")

 <script type="text/javascript">
  $(function () {
   //建立 jquery UI
   InitDialog("My.Helpers.A001");
   //註冊 Angular
   angular.bootstrap(this);
  })
 </script>
 
}

<div ng-controller="My.Helpers.A001">
 <input ng-model="query">
 <select ng-model="sel">
  <option value="Date">ByDate</option>
  <option value="Todo">ByTodo</option>
 </select>

 <ul ng-repeat="item in History | filter:query | orderBy:sel">
  <li>{{item.Date}}/{{item.Todo}}</li>
 </ul>
</div>

@{
 Html.RenderPartial("~/Views/Home/common/DialogView.cshtml");
}

在 Partial 部份,則使用 jQuery 來為元素增加屬性。

<script src="~/Scripts/MyLibs/Dialog.js"></script>
<script type="text/javascript">
 function InitDialog(controller) {

  $("#DialogView").attr("ng-controller", controller);

  var m = new My.Helpers.Dialog( "#DialogView" );
  m.SetTitle("Show");
  m.Open();
 }
</script>

<div id="DialogView">
 <p>{{ForPart}}</p>
 <ul ng-repeat="item in History">
  <li>{{item.Date}}/{{item.Todo}}</li>
 </ul>
</div>

Controller 類,僅產生物件。

 function toLog(obj: any) {
 console.log(obj);
}

module My.Helpers {
 export interface I001 {
  History: M001[];
  //Partial Tip
  ForPart: string;
  //Init Dialog
  InitDialog: () => void;
 }
 export class M001 {
  Date: string;
  Todo: string;
  constructor(pDate:string, pTodo:string) {
   this.Date = pDate;
   this.Todo = pTodo;
  }
 }

 export class A001 {
  constructor($scope: I001) {
   console.log($scope);

   $scope.History = [];
   $scope.History.push(new M001("01", "A"));
   $scope.History.push(new M001("02", "B"));
   $scope.History.push(new M001("03", "C"));
   $scope.History.push(new M001("04", "D"));
   $scope.History.push(new M001("05", "E"));
   $scope.History.push(new M001("00", "Z"));
   
   $scope.ForPart = "Angular to Partial";
  }
 }
}

Partial View 控制 UI 類

function toLog(obj: any) {
 console.log(obj);
}

declare var $;

module My.Helpers {
 export class Dialog {
  Name: string;

  SetTitle(pTitle: string): void {
   $(this.Name).dialog({"title":pTitle});
  }

  Open(): void {
   $(this.Name).dialog("open");
  }

  constructor(pName: string) {
   this.Name = pName;

   $(this.Name).dialog({ autoOpen: false });
  }
 }
}

[JS] AngularJS Tutorial 3

Step_03_篇

昨天花了點時間研究了 Jasmine, 拿來做單元測試還滿方便的…再加上 TypeScript 本身也有支援,用起來感覺超好。而 Angular 本身則有提供這功能,使用上 也更加方便。

//引用
<script src="~/Scripts/angular-scenario.js" ng-autotest></script>

//開始測試
<script type="text/javascript">
 'use strict';

 describe('Unit Test', function () {

  it("Intro", function () {
   var t = "test";
   expect(t).toBe("right");
  });

 });
</script>

filter,也可以自定義 JS 版本的 過瀘器

<div ng-controller="My.Helper.A002">
 <input ng-model='query'/>

 <ul>
  <li ng-repeat="ch in EnChars  | filter:query">[{{$index + 1}}] {{ch}}
  </li>
 </ul>

 <p ng-show="checked">ShowMe</p>

</div>

module My.Helper {
 export interface IA002{
  EnChars: string[];
 }

 // Class
 export class A002 {
  // Constructor
  constructor($scope: IA002) {
   console.log($scope)

   $scope.EnChars = [];
   for (var i: number = 97 ; i < 123 ; i++) {
    $scope.EnChars.push( String.fromCharCode(i) + String.fromCharCode(Math.random() * 100) + String.fromCharCode(Math.random() * 100) );
   }
   //console.log($scope.EnChars);
  }

 }

}

最後,使用 ASP.NET 再實作 Jasmine 時,如果是再同一頁,會發生找不到指定物件的現像。目前只能把 Runner 跟測試頁分開。

//留意!
beforeEach(function () {
 browser().navigateTo('/');
});

describe('Learn', function () {
    
 it('測試_0', function () {
  input('query').enter('a');
  expect(repeater('li').count()).toBe(1);
 });

});

[JS] AngularJS Tutorial 1 & 2 Note

Step_01_篇 Step_02_篇

當使用 AngularJS 與 傳統頁面的差異。反而, Jasmine Wiki 是我覺得比較好玩的,可以直接做單元測試。 雖然不是必需的,但是學習一下對自已 JS 專案的測試會有加成效果。從 lib 看知道有那些功能, jasmine.Matchers.prototype,這些功能都可能在官網那邊找到對應範例。下面則是從 Browser 的代碼做筆記。

describe('描述',function(){
 it('單元測試名稱或內容或目地,會顯示在標頭',function(){
  //預期(來源值)應該為(來源值)
  expect(來源值).toBe(來源值);
 });
});

[JS] AngularJS Tutorial 0-Bootstrapping Note

Step_00_篇

Bootstrap,先偷看一下說明文件…除了原本的 ng-app,AngularJS 讓使用者可以手動決定初始的時 間點。直接切至函式,可以看到 bootstrap(element, modules) 的結構。至於,$provide$injector,還無法很完全的理解,先小記…。

<script src="~/Scripts/angular.js"></script>
<script type="text/javascript">
 $(function () {
  angular.bootstrap(this);
 });
</script>

//網頁語法
<div>
 Hi !! {{UserName}}!
 <input type="text" ng-model="UserName" />
</div>

[JS] AngularJS Note [關於 Watcher 及 scope ]

用 TypeScript 做了一下簡單的測試,與 Knockout 的想法,有異曲同工之妙,bind-with 改由 controller 來做取代。不過光綁定這個動作… 實在加成分數太多。

<div ng-app>
 <div ng-controller="My.Helpers.C0001">
  <p>{{TestValue0 || "請輸入"}}</p>
  <input type="text" ng-model="TestValue0" />
  <input type="button" value="Remove" ng-click="Remove()"/>
  <input type="button" value="Add" ng-click="Add()"/>
 </div>

 <div ng-controller="My.Helpers.C0002">
  <p>{{TestValue1 || "請輸入"}}</p>
 </div>

 <div ng-controller="My.Helpers.C0003">
  <p>{{TestValue2 || "請輸入"}}</p>
 </div>

</div>
function toLog( obj : any) {
 console.log(obj);
}

module My.Helpers {
 export interface I0001 {
  TestValue0: string;
  Add: () => void;
  Remove: () => void;
 }
 export interface I0002 {
  TestValue1: string;
 }
 export interface I0003 {
  TestValue2: string;
 }
 export class C0001 {
  constructor($scope: I0001) {
   // 測試 $$watch 陣列當中值的變動
   $scope.TestValue0 = "C0001";
   $scope.Add = function () {
    this.TestValue0 = "C0001X";
   }
   $scope.Remove = function () {
    delete (this.TestValue0);
   }
   toLog($scope);
  }
 }

 export class C0002 {
  constructor($scope: I0002) {
   $scope.TestValue1 = "C0002";
   toLog($scope);
  }
 }

 export class C0003 {
  constructor($scope: I0003) {
   $scope.TestValue2 = "C0003";
   //每個 Ctrl 有個自的 $$watchers...
   //而 scope 也會自動分配,可以從 物件有 add 函式,
   //而物件2,3都沒有該項函式中知道
   toLog($scope);
  }
 }
}

[C#][Dictionary] 基本運用

小記一下,再 C++ std::map::find常用這指命來取得對應的資訊,只要結果不等於 map::end,就表示有找到對應的值,但在 C# 當中,如果直接使用 key 來驗證是否為 null,則會造成 nullable exception,學習長知識一下。

using System;
using TestConsol.MyLibs;

namespace TestConsol
{
 class Program
 {
  static void Trace(T param)
  {
   Console.WriteLine(param);
  }

  static void Main(string[] args)
  {
   Trace("test");

   TestDic temp = new TestDic();
   temp.AddData("a","is a");
   temp.AddData("a", "is b");
   
   Console.WriteLine("Value ==> {0}", temp.HasDataByKey("a") );

   Console.WriteLine("Value ==> {0}", temp.GetDataByKey("a") );

   Console.ReadKey(true);
  }
 }
}

取資料當然也可以使用 return dicData.FirstOrDefault( x => x.Key == _key ).Value; 但這樣會變成使用 IEnumAble iterator,如果是使用 List 應該就很建議使用。原因應該很多達人都有分享,不再累述。

using System.Collections.Generic;

namespace TestConsol.MyLibs
{
 /// <summary>
 /// @link http://www.dotnetperls.com/dictionary
 /// @link http://msdn.microsoft.com/zh-tw/library/xfhwa508(v=VS.95).aspx
 /// </summary>
 class TestDic
 {
  /// <summary>
  /// 資料儲存區
  /// </summary>
  private Dictionary<string, string> dicData = null;
  public TestDic() {
   dicData = new Dictionary<string, string>();
  }

  /// <summary>
  /// 加入資訊
  /// </summary>
  /// <param name="value"></param>
  public void AddData( string _key, string _value  ){
   if (!HasDataByKey(_key))
   {
    dicData.Add(_key, _value);
   }
   else {
    dicData[_key] = _value;
   }
  }

  /// <summary>
  /// 經由 Key 取得資料
  /// </summary>
  /// <param name="_key">ID 值</param>
  /// <returns></returns>
  public string GetDataByKey(string _key)
  {
   //return dicData.FirstOrDefault( x => x.Key == _key ).Value;
   if (HasDataByKey(_key))
   {
    return dicData[_key];
   }
   return null;
  }

  /// <summary>
  /// 是否已經有這筆資料
  /// </summary>
  /// <param name="_key"></param>
  /// <returns>true 則表示有這筆資料</returns>
  public bool HasDataByKey(string _key) {
   return dicData.ContainsKey(_key);
  }

 }
}


[JS][Knockoutjs]Todo 練習

最近在練習 Angular 突然覺得,應該也要補一下 knockoutjs 的練習。本來還有 Tempalte 的運用,但是覺得實用性好像不高,就沒有加進來了。

  • 日期:
    內容:

順便補一個,TypeScript 的寫法,再引數當中,也是可以這樣使用的。

Note(T: { value; todo; }) {
 //console.log(T.value);
}