angular: controller As 与 $scope

简单地说,如果设置了{controllerAs:main}, 则 $scope['main'] =  new MainController(); 意即别名会则为控制器$scope的一个属性存在。具体可参照:

http://codetunnel.io/angularjs-controller-as-or-scope/

——————

在视图中具名的form是一个默认的FormController,由angular生成并设定。在form的父控制器中可以访问到这个form控制器的一些属性,如: $scope.myFormName.myFieldName.$valid 等。具体参见angular手册:

https://docs.angularjs.org/api/ng/directive/form

延迟绑定,即在修改一个字段时(onchange事件)不想立刻将修改的字段反映到其他视图中时,可以在 字段加入绑定选项: <input ng-model="myModel" ng-model-options="{updateOn: 'submit'}" />,因为默认是在失去焦点后就修改视图,可以改成在提交表单后才修改视图。在提交表单时,需要注意提交model的更新:

 scope.myForm.$commitViewValue();
// scope.myForm.myField.$commitViewValue();

参考链接如下:

https://code.angularjs.org/1.4.10/docs/api/ng/directive/ngModelOptions

Bootstrap:弹性搜索框

<form action="" method="get" class="form-horizontal">
        <div class="input-group search-input-group">
           <input type="hidden" name="scope" value="1">
             <input name="key" autocomplete="off" type="text" class="form-control" placeholder="输入要搜索的内容关键字" >
              <span class="input-group-addon">
                        <button type="submit">
                            <span class="glyphicon glyphicon-search"></span>
                        </button>  
                    </span>
        </div>
      </form>

 

对应的CSS:

.search-input-group .input-group-addon{
    background: white !important; 
}
.search-input-group .form-control{
    border-right:0; 
    box-shadow:0 0 0; 
    border-color:#ccc;
}
.search-input-group{
    width: 40%;
}
.search-input-group button{
    border:0;
    background:transparent;
}
.search-input-group input:focus + button{
    z-index:3;
}
.search-input-group input{
    -webkit-transition: width  0.2s ease-in-out;
    -moz-transition:width  0.2s ease-in-out;
    -o-transition: width  0.2s ease-in-out;
    transition: width  0.2s ease-in-out;
}
.search-input-group input:focus{
    width: 500px;
}

若想把搜索图标放到输入框的前面,bootstrap其实是不支持的,需要自己定制一下。可以试试以下链接:

http://bootsnipp.com/snippets/featured/support-glyph-and-fa-icon-inside-input

最近遇到的一些坑集合

Angular

异步获取到的数据,在视图上使用自定义filter时,控制台总是报错 input undefined ,这是因为filter会在anagular的第一次消息循环时尝试运行,异步数据尚未加载进来,尝试绑定时数据固然不存在。所以要做判断。

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider{ 
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            context.OwinContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
   //....

}
}

CORS

基于web api的应用常常使用基于token的验证方式进行api的访问管理。一般步骤是:

(1)用户输入用户名和密码,提交到web api host.

(2)web api host验证后,返回token给Client, Client使用Cookie存储下来。

(3)后续Client继续是用token访问web api, web api做验证。

这个方法比较简单可行, 资源服务器和验证服务器部署在一个进程里。但是最大的问题是,token过期后如何刷新的问题。简单的方法是把token的过期时间设置的比较长,如一个 月,但不够安全,不符合token的设置本意,所以需要用refresh token的验证机制。简单地说就是,web api host验证后返回两个token,一个是基本的access token,另一个是refresh token。access token过期后,可以用refresh token换取一个新的access token。这里遇到一个cors的问题。即使在web api 的config里加了如下语句:

public static void EnableCors(HttpConfiguration config)
        {
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);
        }

也不行,原因是oauth server的获取access token,不直接经过web api。所以要对oauth server的响应头添加allow-origin。具体如下:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            context.OwinContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
           //....
       }
}

但是,依然有问题。因为浏览器会发出预检请求(preflight ),api host不能正确应答,以前的cors配置风格不支持预检请求,故需要:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
   }
}

问题即可解决。参考地址:

http://stackoverflow.com/questions/24989769/cors-is-not-working-in-web-api-with-owin-authentication

http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

Entity Framework 的一次迁移记录

Migration已经变成通用的做法,laravel框架也有这个东西。今天我对已经存在的网站增加了一些model,但是以前也没怎么用Migration。使用时遇到一些问题,记录一下。

1. 对于已经存在的数据库,如有_MigrationHistory表,先将它删掉。

2. 在VS里执行第一个迁移命令: Enable-Migrations -Force  将生成Migration文件夹和一个Migration类。

3. 执行Add-Migration InitialCreate –IgnoreChanges  产生一个空基架,其中-IgnorceChanges是关键。

»阅读全文

利用微信服务号开发邀请好友同时获得优惠券功能

为了推广需要,想在微信服务号里加入一个邀请好友关注服务号获得优惠券的功能。如A已关注了微信服务号,他想邀请他的好友B也关注该微信号。B关注后,A和B都将获得一个优惠券。具体的操作过程如下:

1.A关注微信服务号;

2.微信服务号的菜单有【我的邀请码】,A点击该菜单服务号向用户发送一张二维码,该二维码是携带了A的ID信息和其他扩展信息的。并同时发送一句与此类似的说明:“请将该二维码发送给您的朋友,您和您的朋友都将获得更多优惠券。”

3.A将二维码转发给自己的好友B;

»阅读全文

[知识点]nchar,char,varchar与nvarchar区别

char, 固定长度,固定长度因为数据结构的原因读取和写入的速度快。如Type:char(10),当Type=‘doc’是,右边会有7个空格,这也是为什么使用orm后获得对象后面有一大串空格的原因,需要使用trim去掉。

varchar,可变长度,用多少开辟多少,节省空间,但读写速度会受影响。

nchar,固定长度,不过数字和英文是都占用两个字节,适合有其他语言特别是中文的情形。N表示Unicode常量,可以解决多语言字符集之间的转换问题。

nvarchar,同上。

不加n,可以存储8000个字符,加n后则可以存储4000个。

Tags: 知识点,char

Entity Framework 迁移的使用场景

EF拥有迁移功能,虽然很强大,但还是需要明白这一个功能的目的和使用场景。一般情况下,当你是用Code First时,Migrations就很有必要了。例如,你在生产环境中,经常更新Poco对象,而初始化器使用的是DropCreateDatabaseAlways或者DropCreateDatabaseIfModelChanges,那么你的数据库中总是处于初始化状态,如果想保留一部分数据,很遗憾,当部署到产品环境中时数据将会丢失。我们希望即使在产品环境下,以前保存的数据不会被丢失。简单地说:

»阅读全文

EF错误描述集

Poco对象生成的数据表自动添加了外键列

设计Poco对象时给UerProfile添加了一个集合属性: 

public class UserProfile
{
    public UserProfile()
    {
        this.Departments = new List<Department>(2);
    }
    public IList<Department> Departments{get;set;}
  }

这个Departments并不想加入EF字段管理中,虽然已经在DbModelBuilder中移除了所有的惯例,但是还是自动被EF在Departments表中添加了一个UserProfile_ID字段。解决方式是:使用Ignore方法移除掉Departments集合属性即可。

"Cannot drop database "MiniOA" because it is currently in use."

出现以上错误的触发条件是:

»阅读全文

使用EF创建LocalDb时遇到的一些问题

EF在本地使用localDb创建数据库时,如果同步git到服务器会出现App_Data下的mdf和ldf文件不可写的问题,原因是本地的localdb服务没有关闭,可以使用:

sqllocaldb.exe stop v11.0
sqllocaldb.exe delete v11.0

关闭和删除数据库,再同步就没有问题了。

另外在调试时可能会出现“EF5: Cannot attach the file ‘{0}' as database '{1}'”之类的问题,你可以简单地做两个操作:一是把App_Data下的数据库文件删除了,如果还不起作用,再使用上面的两个命令给干掉。

Entity Framework的关系配置

实体类映射中,关系的映射配置在关系的两端都可以配置。例如,用户信息与登录信息的 一对多 关系可以在用户信息端配置:

HasMany(m => m.LoginLogs).WithRequired(n => n.Member);

等效于在登录日志信息端配置:

HasRequired(m => m.Member).WithMany(n => n.LoginLogs);

但是,如果所有的关系映射都在作为主体的用户信息端进行配置,势必造成用户信息端配置的臃肿与职责不明。所以,为了保持各个实体类型的职责单一,实体关系推荐在关系的非主体端进行映射

»阅读全文