精华内容
下载资源
问答
  • 现在,当PDF如此流行并且我们大多数人在家工作时,人们的心中还有另一个问题如何对PDF进行数字签名? 下面小编和大家一起来探讨一下为什么在线PDF签名很棒,以及如何立即创建数字签名。 为什么要以电子方式签署...

    PDF文件在我们的生活工作中用到的越来越多,在现代文档中占据的位置也越来越大,PDF文件几乎可以由任何图形应用程序或浏览器打开,而最重要的是,它不会改变其中的样式和内容,这是文档世界的重大突破。 现在,当PDF如此流行并且我们大多数人在家工作时,人们的心中还有另一个问题:如何对PDF进行数字签名? 下面小编和大家一起来探讨一下为什么在线PDF签名很棒,以及如何立即创建数字签名。
    为什么要以电子方式签署PDF
    想想您以前如何签署文档。有人会向您发送合同。您将其打印出来,手动签名,扫描,对扫描的文件进行一些调整(例如,文件大小,质量,裁切),然后将其发送回去,然后切碎打印的纸张。每天重复多次。
    如果考虑到整个公司的规模,不仅打印和切碎纸张是非常浪费的,生成的文件也不是每个人都开始使用的漂亮的PDF,而是图像,实际上可能是未对齐的,未经颜色校正的,并且无法在其中选择文本他们。
    如果您学习如何电子签名PDF文档,不仅可以节省大量时间和纸张,还可以保持每个文档的设计和功能完好无损,因此其他任何人也都可以充分利用该功能。精美的PDF格式。
    如何在Mac上创建数字签名
    您可能会惊讶于Mac上已经有免费的PDF签名功能。实际上,用于打开图像的默认应用程序(例如“预览”和“快速查看”)可以对PDF进行签名。您甚至可以学习如何在不离开MAIl应用程序的情况下发送PDF。
    让我们从如何首先向PDF软件添加签名开始。所有预安装的Mac应用程序都共享其签名。因此,如果您在“预览”中创建数字签名,则也可以自动在“快速查找和邮件”中使用它。
    在预览中创建数字签名:
    1、从应用程序启动预览
    2、在菜单栏中,导航到工具➙注释➙签名➙管理签名…或单击标记工具中的签名图标,然后选择创建签名。
    3、有两个选项:您可以使用触控板以数字方式绘制签名,也可以在纸上签名并通过Mac的相机进行扫描。
    4、要创建数字签名,请选择“单击此处开始”并开始绘图。请注意,触控板实际上是显示在屏幕上的。因此,将其视为一张纸,完成后按任意键。单击清除以重新开始,或者单击完成。
    5、要扫描您的物理签名,请导航至“相机”选项卡,然后将您的物理签名保持在相机上方,使其与基线对齐。识别您的签名后,单击“完成”。
    在这里插入图片描述
    如前所述,如果要在“快速查找和邮件”中重复执行相同的过程。无论如何,您的签名将对所有这些应用程序都可用。但是您可能想知道是否还有其他选择。
    PDFpen是真正功能齐全的专业级PDF编辑应用程序,它不仅使您可以签署文档,而且还可以重新排列页面,合并单独的文档,编辑敏感信息,借助OCR技术识别图像中的文本,等等。想象一下,您需要在一个应用程序中管理完成的所有文书工作。
    PDFpen Pro 12 for mac(PDF编辑器)
    立即下载
    PDFpen Pro 12 for mac(PDF编辑器)
    PDFpen Pro 12 for mac是一款应用在MacOS上的PDF编辑器,PDFpen Pro Mac集添加文字,图片和签名于一体,可以填写PDF表格,合并或拆分PDF文档。重新排序和删除页面。使用PDFpen Pro创建可填写的表单和内容表,macz提供PDFpen Pro 12 for mac版下载。
    2020-07-16134 MB英文软件
    如何快速签署PDF
    在“预览”(或“快速查找”或“邮件”)中创建数字签名后,对文档进行签名将变得轻而易举。
    如何在预览版中对PDF进行数字签名:
    1、打开任何需要签名的文档
    2、点击“标记”菜单中的签名图标,然后选择您要使用的图标
    3、将签名放置到位(您可以通过拖动角来调整其大小),然后单击关闭
    4、保存或导出PDF以保存您的签名
    该过程在“快速查看”中完全相同,但在“邮件”应用中略有不同:
    1、打开邮件并开始新消息(⌘+ N)
    2、将PDF文件拖到其中
    3、将鼠标悬停在PDF上,单击下拉箭头,然后选择“标记”
    4、对预览重复上述步骤
    5、点击完成
    出于安全原因,PDFpen不会将您的签名保存在应用程序中,并会提示您每次进行电子签名PDF:
    1、在PDFpen中打开交互式表格PDF
    2、单击签名字段
    3、使用触控板签署文件
    4、双击以完成签名
    5、点击确定
    另外,如果您已经有一个带有透明背景的签名(例如.png格式),则只需在PDFpen中插入签名并以这种方式保存文档。
    如何删除PDF签名
    当涉及删除旧签名或使您的私生活更安全时,“预览”,“快速查找”和“邮件”为您提供一种删除以前保存的签名的简便方法:
    1、在预览中,在“标记”菜单中选择签名图标
    2、点击您要删除的签名旁边的叉号
    如上所述,PDFpen不会在应用程序中保留已保存的签名,因此您完全不必担心将其删除。
    其他改善PDF的方式
    尽管PDFpen可以让您进行几乎可以想象的任何修改,但您的工具箱中可能还包含其他一些应用程序,可以改善您的日常PDF工作流程。
    PDF Search是一种由AI驱动的独特算法,可帮助您查找给定PDF中的任何数据位。当您的生活围绕处理文件时,Preview仅带您走了那么远。使用PDF搜索,您可以在一个或多个PDF中找到特定的搜索词匹配项,相关术语,排名结果等等。
    PDF Search for Mac(pdf文件搜索工具)
    立即下载
    PDF Search for Mac(pdf文件搜索工具)
    PDF Search Mac特别版是Mac平台上的一款PDF文件快速搜索工具,可以进行相关性搜索,以便在数千个PDF文档之间立即找到最相关的页面,提高工作效率!
    2020-08-102.99 MB英文软件
    PDF Squeezer是一款功能强大的工具,可立即压缩PDF文件。只需将PDF放入其中即可完成。您也可以一次处理多个PDF(仅使用一个PDF文件夹),而没有任何明显的质量变化。PDF Squeezer甚至可以使用受密码保护的文件,而保留所有敏感信息。
    PDF Squeezer for Mac(pdf压缩器)
    立即下载
    PDF Squeezer for Mac(pdf压缩器)
    PDF文件过大?PDF文件过大,传输费时间?PDF文件过于占用空间?pdf压缩器—PDF Squeezer Mac推荐给大家!pdf Squeezer Mac使用简单,点击即可减小PDF尺寸…
    2020-06-2318.35 MB简体中文
    所以,您可以学习如何使用Mac内置的工具在几分钟内创建数字签名。但是,还有一个专门针对使工作流程尽可能高效而量身定制的PDF工具。您可以使用PDFpen修改任何文件,使用PDF Search查找确切的关键字,并使用PDF Squeezer减小文件大小。
    以上就是MacZ小编为您分享的“如何在Mac上快速签署PDF,来看这篇超全面分析!”,希望对你有所帮助,更多Mac软件使用技巧请关注MacZ更多文章。

    展开全文
  • 慢日志查询MySQL的慢日志查询是MySQL提供的一种日志记录,它用了记录在MySql中响应时间超过...比如一条sql执行超过5秒钟,我们就算慢SQL,MySQL会记录超过5秒的sql,我们可以结合explain进行全面分析。默认情况下,...

    慢日志查询

    MySQL的慢日志查询是MySQL提供的一种日志记录,它用了记录在MySql中响应时间超过阈值的语句,具体运行时间超过long_query_time值的SQL,则会被记录到慢日志中。long_query_time的默认时间为10,意思是运行10以上的语句。

    比如一条sql执行超过5秒钟,我们就算慢SQL,MySQL会记录超过5秒的sql,我们可以结合explain进行全面分析。

    默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数。当然,如果不是调优需要,一般不建议启动该参数,因为慢日志会或多或少带来一定的性能影响。

    是否开启以及设置#查看是否开启show variables like '%slow_query_log%';#开启set global slow_query_log = 1;

    使用set global slow_query_log=1开启了慢查询日志只对当前数据库生效,如果MySQL重启后则会失效。如果要永久生效,就必须修改配置文件my.cnf。

    注意设置慢查询阈值时间后,你可能看不到值发生了变化,即没有生效,这时需要重新连接或新开一个会话才能看到修改值。show variables like '%long_query_time%'

    或者不重开连接也可以使用下面的命令:show variables like '%long_query_time%'

    哪些sql会被慢日志记录,这是由参赛long_query_time控制,默认情况下long_query_time的值为10秒,命令:show variables like '%long_query_time%';

    假如运行时间正好等于long_query_time的情况,并不会被记录下来。也就是说,在mysql是判断大于long_query_time,而非大于等于。

    可以用下面的语句做个测试SELECT sleep(4)

    如果你设置的long_query_time为3秒,那么这条语句就会被记录下来。

    7b168df6e9c051186580470674b83665.png

    查看慢日志条数show global status like '%slow_queries%'

    日志分析工具mysqldumpslow

    在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySql提供了日志分析工具mysqldumpslow。

    例如:#得到返回记录集最多的10个SQL

    Mysqldumpslow –s r –t 10 D:\Program Files\mysql\data\DESKTOP-VN2D5OU-slow.log#得到访问次数最多的10个SQL

    Mysqldumpslow –s c –t 10 D:\Program Files\mysql\data\DESKTOP-VN2D5OU-slow.log#得到按照时间排序的前10条里面含有左连接的查询

    Mysqldumpslow –s t –t 10 –g “left join” D:\Program Files\mysql\data\DESKTOP-VN2D5OU-slow.log#另外建议在使用这些命令时结合|和more使用,否则可能出现爆破情况

    Mysqldumpslow –s r –t 10 D:\Program Files\mysql\data\DESKTOP-VN2D5OU-slow.log|more参数含义

    s: 表示按照何种方式排序

    c:访问次数

    l:锁定时间

    r:返回记录

    t:查询时间

    al:平均锁定时间

    t:返回前面多少条的数据

    g:后面搭配一个正则表达式

    用show profile进行sql分析

    show profile命令可以分析当前会话中语句执行的资源消耗情况。用于查找SQL耗时瓶颈 。默认处于关闭状态,并保存最近15次的运行结果。

    查看是否开启(show variables like ‘profiling’;)

    开启功能(set profiling = on;)

    开启之后就可以记录接下来sql的运行情况。之后通过show profiles来查看结果:

    a8396c1d83b917a22085b49077ba6108.png

    进一步通过命令(show profile cpu, block io for query 3;)分析某个SQL语句执行情况,例如下面分析3号SQL的情况。

    feb4fafc7a04a44764e914d9400e1ae7.png

    Show profile后面的一些参数:All:显示所有的开销信息

    Block io:显示块IO相关开销

    Context switches: 上下文切换相关开销

    Cpu:显示cpu相关开销

    Memory:显示内存相关开销

    Source:显示和source_function,source_file,source_line相关的开销信息

    全局查询日志

    (永远不要在生产环境开启,查看所有执行的SQL语句)

    设置命令:set global general_log = 1;#以表的形式输出set global log_output = ‘TABLE’

    此后,mysql所执行的SQL语句将会记录到mysql.genearl_log表,可用下面的命令查看:select * from mysql.general_log;

    也可以在配置文件中配置,设置如下:#开启General_log = 1#记录日志文件的路径General_log_file = D://path/logfile#输出格式Log_output=file

    展开全文
  • 本文是我在设计环节遇到问题并寻求解决方案过程中总结沉淀下来的几点小结,希望能为设计师伙伴们提供一些启发或帮助。背景需求源于一款产品意在提升桌面图标的生成率,所以业务侧希望在用户退出该产品时以弹窗的形式...

    前言

    “行动按钮”作为连接用户与产品的交互触点,在产品设计中扮演了至关重要的角色,一个优秀的按钮控件可以有效的提升交互体验,引导用户,提升产品转化率。本文是我在设计环节遇到问题并寻求解决方案过程中总结沉淀下来的几点小结,希望能为设计师伙伴们提供一些启发或帮助。

    背景

    需求源于一款产品意在提升桌面图标的生成率,所以业务侧希望在用户退出该产品时以弹窗的形式引导用户创建图标。针对该需求,在弹窗行动按钮的优先级表达、行退操作布局设计中产生了疑惑,主要体现在以下4个方案中,页面示意如下:

    c632a779c17ba42e4708f775a571d870.png
    e8576e5f931f2247c3ed9adfdb019036.png

    发现问题

    • 按钮的优先级该如何表达?
    • 行进、后退该如何放置?
    • 业务侧与用户侧该如何权衡?

    问题聚焦

    • 行动按钮的优先级表达规范
    • 行动按钮的召唤行为分析
    • 行动按钮的本源分析

    Part 1. 行动按钮的优先级表达规范

    通过对 Material Design、简书、IXDC、MicroUX及设计相关文献的查阅归纳,对中行动按钮的规范、经验总结提炼如下:

    按钮的优先级表达可划分为三个层级

    具备高度强调作用的“填充(包含)按钮”、中度强调的“轮廓(概述)按钮”、低度强调的“文本按钮”。

    4f3a40022a6808aa349f3638c209d604.png

    正确表达

    单个突出按钮:布局中应包含一个突出的按钮,以使其他按钮在层次结构中的重要性降低。此高强调按钮吸引了最多的关注。

    1781d248f0984a751edbece312382164.png

    多个按钮:一个应用一次可以在(模态弹窗/底部栏)布局中显示多个按钮,因此高强调按钮可以与执行次要功能的中强调按钮和低强调按钮配合使用。

    可以在填充的按钮(高强调度)旁边放置一个轮廓按钮(中等强调)。

    085597ab7bdecdc11a68c737a109b394.png

    可以在轮廓按钮(中等强调)旁边放置一个文本按钮(低强调)。

    965cc443bd141bce3f3ef901b5e25328.png

    使用多个按钮时,指示更重要的操作时,请将其放置在填充的按钮中。

    66d9b65de2d9cae43d7c888ab2632dee.png

    文本按钮通常嵌入在包含的组件(如卡片和对话框)中,以使其自身与出现它们的组件相关联。

    4864c15729967f536afc87ee74e1c436.png

    文本按钮间又可以通过颜色,粗细进行优先级区分。

    1f41aed9c8c35980cd31a45615405ec7.png
    9a6a7e3d4ae8b9dcc2fad0914b663166.png

    尽量避免

    避免同时并列使用两个填充按钮(高优先级按钮)。

    Part 2. 弹窗中行动按钮的召唤行为分析

    用户惯性认知:左后退,右行进

    294f1141008716b60de55b0b1c410c32.png

    论据说明:

    头部平台情况

    • iOS的移动、电脑设备绝大多数情况下行进按钮都在右侧,后撤在左侧;
    • 早些时候,win与Android都为左前进,右后撤。而Android在4.0版本发布后也将按钮调换为了“左后退,右行进”,顺应了设计的大趋势。

    A/B test数据结论。

    早在 2004 年,就有 Walker 和 Stanley 的两人针对这个问题做了对比研究实验,实验选取定量测试者对程序进行操作,进行两轮测试并分别在按钮位置与问题上做了调换;

    05959367808734ff2a858dfc414ea554.png
    e59c5359b8faea52156bdc3ed4752114.png

    实验结果:在第一次实验中,A、B两实验组行进与后退的正确率相差无几,未达到(统计学中)“有感”;第二次实验(A、B组调换位置,并问相反的问题),A组变化不大,B组错误率高出三倍。(资料来源:《体验进阶》)

    8ff0396c58e8810d79b87b4f278ee890.png

    结论:该实验告诉我们一个道理,即不要轻易违背用户习惯。为了提高效率,人们通常只会在第一次接触新事物时,启用大脑,之后大部分情况都处于“无意识状态”。

    行业情况

    PC端。源于眼动视觉轨迹:自左向右的浏览习惯,因此行动按钮一般为:左行进,右后退。

    77325174b780c35f404f354c90b573be.png

    △ PC端(win系统):左行进,右后退

    移动端

    • 便于大多数右利手用户单手持机操作;
    • 符合古腾堡法则:左上角是视觉的第一落点区,而右下角是视觉最终落点区,右侧行进可避免阅读视线顺序造成无意识的回跳。
    09a84c6ff0f55b3cbfbd424982b6b485.png

    △ 移动端:左后退,右行进

    按钮的召唤行为

    通常,我们在产品中会为了达成某种指标,需要在界面上引导用户去完成我们希望其完成的操作。且这类操作是可以达成某种目的的,我们把这类操作称为「召唤行为」,该按钮称为召唤按钮,又称CTA(Call To Action),即从元素的角度引导用户完成任务,提升产品转化率。

    24538753c1dd60bf75b850a55d888eca.png

    △ 召唤行为:取消

    2175a406e3808bb6dce869e0704cccc5.png

    △ 召唤行为:取消

    a55753c8695cef4cbe1c0ce65bfc1911.png

    △ 召唤行为:继续选座

    e7ddda86a34eee1b15dd176b27a9ad1e.png

    △ 召唤行为:继续选座(调换位置虽然能暂时解决用户的退出行为,但容易产生误操作,与用户的期望不同,导致在产品体验上会被用户排斥)

    在模态弹窗下,还需要配合不同弹窗类型的标题文案/说明文案意向以及使用场景,来进行召唤按钮的设计,举例示意如下。

    a163617d38d430eec08cf7c70b2d19f4.png

    小结:在移动端产品行动按钮设计中,一般回退操作在左,行进操作在右,召唤属性根据场景、弹窗标题等对按钮做突出处理。

    Part 3. 模态弹窗下按钮的召唤行为优先级程度评估

    以上是站在用户体验角度对按钮设计的分析,那么,在实际的方案设计到落地过程中,我们不仅要满足用户体验,同时也要站在业务方的角度看待问题,综合评估业务价值与用户体验,最终权衡两者得到的最优方案。那么如何评估召唤行为的强弱以及权衡业务价值与用户体验关系呢,小编有以下几点建议。

    依据产品业务性质

    183e404787179408d6d87690ce85caa5.png

    依据产品生命周期

    a3f34c21c2a7be8d3914a666a51b90bb.png

    归纳&总结

    • 「召唤按钮优先级表达」:包含的按钮>概括按钮>文本按钮(文本颜色、加粗)。
    • 「行动按钮位置循序」:左回退,右行进,核心是建立并遵循用户惯性认知,不随意打破。
    • 「召唤行为内核」召唤行为不是用户想做的事,而是我们应该要让用户做的事,但不是强迫。
    • 「召唤行为优先级程度评估」:需要结合需求的触发场景,区分所处的产品业务性质,确定所处的产品生命周期。

    想要学习或者提升设计可以来AAA教育。

    相关推荐:

    5分钟完成一张概念设计?

    设计师如何增加工作效率?

    移动端横向滑动的设计总结

    设计中用到的三条设计曲线

    网页设计404页面技巧和示例

    展开全文
  • Directive全面分析

    2016-01-15 10:56:00
    说到Angularjs directive即指令,可以这么说Angularjs的灵魂就是指令,学会Angularjs指令那么你的Angularjs...学习Angularjs directive那么我们要带3个问题来学习: 1. 什么是angular 指令?2. 指令如何定义存储的...

    说到Angularjs directive即指令,可以这么说Angularjs的灵魂就是指令,学会Angularjs指令那么你的Angularjs的武功就修炼了一半了,当然这只是鄙人的一点点独到见解,废话不多说,以下是Angularjs 指令的运用及源码实现解读。

    学习Angularjs directive那么我们要带3个问题来学习:

    1. 什么是angular 指令?
    2. 指令如何定义存储的?
    3. 指令如何编译运行的?

    1.首先第一点解读什么是指令:

    At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.(官网是这么说的)

    指令就是一些附加在HTML元素上的自定义标记(例如:属性,元素,或css类),它告诉AngularJS的HTML编译器 ($compile) 在元素上附加某些指定的行为,甚至操作DOM、改变DOM元素,以及它的各级子节点。(这是鄙人通过解读官网定义的个人见解)

    从中可以看出指令就是自定义的html标签用来解决反复的的CRUD(创建 读取 更改 删除)操作来修改DOM,这里小伙伴们如果想深入学习Angularjs操作DOM,那么小伙伴们首先需要了解D1、D2、以及D3实现了什么以及结构的优化有什么。再来学习Angularjs就会一步冲天!

    好第一点我们知道了概念那么我们看看具体怎么使用Angularjs 指令吧:

     

    指令实例:

    <div ng-controller="Controller">
      Hello <input ng-model='name'> <hr/>
      <span self-app></span> <br/>
      <span self:app></span> <br/>
      <span self_app></span> <br/>
      <span data-self-app></span> <br/>
      <span x-self-app></span> <br/>
    </div>

    在这里可以看出如果指令注册为Attribute(属性)那么有5中合法的调用方式:

    第一种以_来调用指

    第二种以:来调用指令

    第三种以-来调用指令

    第四种以data-XXX-XXX来调用指令

    第五种以x-XXX-XXX来调用指令

    2.第二点解读指令如何定义存储的

    指令通过

    angular.module('selfApp', [])
    .directive('myDirective', function() {
    // 返回一个对象(暂且称之为指令对象)
      return {
        restrict: 'A',//E A M C
        replace: true,
        scope: true,
        template: '<span>hello world</span>',
        compile: function (tElement) {
          console.log('complile: ', tElement);
          return function (scope, elem) {
            console.log('1');
          }

        }

      }

    });

    这里我们可以看出来通过我们事先注册的module来第一了一个指令,我们如果想了解指令如何存储的 那么就要看看源代码了,

    directive: invokeLaterAndSetModuleName('$compileProvider', 'directive')//angular.js 2172行

    这是angularjs module的内部方法,

    //延迟调用并设置模块名称

    function invokeLaterAndSetModuleName(provider, method) {
      return function(recipeName, factoryFunction) {

    //给工厂函数的module变量命名即给模块命名
        if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;

          //把我们注册的指令存储到调用队列中
          invokeQueue.push([provider, method, arguments]);

          //返回我们的模块实例
        return moduleInstance;
      };
    }

    这里我们可以知道其实我们注册一个指令其实只是把我们的指令存储到了调用队列中等待调用。

    3. 第三点解读指令如何编译运行的?

    其实调用的时候就是编译Angularjs directive的时候也就是angularjs自己的编译机制,会使用$CompileProvider的directive方法来编译指令,compileProvider方法如下:

    //这里其实是吧$CompileProvide注册为一个服务来调用

    $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];//angular.js 6919行
    function $CompileProvider($provide, $$sanitizeUriProvider) {

    好了重头戏来了

    // 指令存储容器,一个指令可以有多个指令工厂函数(即多个指令对象)

    this.directive = function registerDirective(name, directiveFactory) {

      
      assertNotHasOwnProperty(name, 'directive');

      //这里不用说了吧检验指令名称是否为字符串类型
      if (isString(name)) {

        //还是检验指令名称是否合法
        assertValidDirectiveName(name);

        //构造一个指令工厂
        assertArg(directiveFactory, 'directiveFactory');

        // 检验该指令是否有指令工厂 如果没有就继续
        if (!hasDirectives.hasOwnProperty(name)) {
          hasDirectives[name] = [];

          $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
            function($injector, $exceptionHandler) {

             // 定义一个指令工厂集合
              var directives = [];

             // 循环遍历指令工厂集合,并收集每个工厂函数返回的指令对象
              forEach(hasDirectives[name], function(directiveFactory, index) {
                try {

                 // 调用工厂函数,这里用的是$injector,所以工厂函数也可以是一个拥有依赖注入的函数或数组
                  var directive = $injector.invoke(directiveFactory);

                 //检查指令是否是一个函数 即我们之前定义的指令其实是一个函数
                  if (isFunction(directive)) {
                    directive = { compile: valueFn(directive) };

                 //如果指令中存在compile函数就不运行link函数
                  } else if (!directive.compile && directive.link) {
                    directive.compile = valueFn(directive.link);
                  }
                  directive.priority = directive.priority || 0;
                  directive.index = index;
                  directive.name = directive.name || name;
                  directive.require = directive.require || (directive.controller && directive.name);
                  directive.restrict = directive.restrict || 'EA';
                  var bindings = directive.$$bindings =
                  parseDirectiveBindings(directive, directive.name);
                  if (isObject(bindings.isolateScope)) {
                    directive.$$isolateBindings = bindings.isolateScope;
                  }
                  directive.$$moduleName = directiveFactory.$$moduleName;
                  directives.push(directive);
                } catch (e) {
                $exceptionHandler(e);
              }
            });
            return directives;
          }]);
        }

     // 存储当前指令工厂
      hasDirectives[name].push(directiveFactory);
    } else {
      forEach(name, reverseParams(registerDirective));
      }

     // 最后提供链式调用
      return this;
    };

    好了源代码解读完成,大家是不是对指令有了一个系统的概念,而且也知道angularjs directive是怎么运行下来的了,那么总结一下:

    1. 注册指令时,注册的是工厂函数(支持依赖注入),它负责返回指令对象
    2. 一个指令可以注册多个工厂函数,就意味着将对应多个指令对象(即指令对象集合),其实多个指令对象之间是有一些冲突的,比如只能拥有有一个模板,拥有一个孤立作用域等
    3. 一个指令对应的指令对象集合是通过注册为服务的方式被外界获取的

    好,下面介绍定义一个指令时内部参数的解读:(作为一名专业的it工作者,做戏就要做全套!)

    name -  当前scope的名称,注册时可以使用默认值(不填)。

    priority - (优先级)- 当有多个directive定义在同一个DOM元素时,有时需要明确它们的执行顺序。这属性用于在directive的compile function调用之前进行排序。如果优先级相同,则执行顺序是                不确定的(经初步试验,优先级高的先执行,同级时按照类似栈的“后绑定先执行”。另外,测试时有点不小心,在定义directive的时候,两次定义了一个相同名称的directive,但执行结                  果发现,两个compile或者link function都会执行)。

    terminal - (最后一组起作用)

                  - 如果设置为”true”,则表示当前的priority将会成为最后一组执行的directive。任何directive与当前的优先级相同的话,他们依然会执行,但顺序是不确定的(虽然顺序不确定,但基本上                   与priority的顺序一致。当前优先级执行完毕后,更低优先级的将不会再执行)。

    scope -  true - 将为这个directive创建一个新的scope。如果在同一个元素中有多个directive需要新的scope的话,它还是只会创建一个scope。新的作用域规则不适用于根模版(root of the                           template),因此根模版往往会获得一个新的scope。这个scope是一个新的、独立(isolate)的scope。”isolate” scope与一般的scope的区别在于它不是通过原型继承于父scope的。这对                 于创建可复用的组件是很有帮助的,可以有效防止读取或者修改父级scope的数据。这个独立的scope会创建一个拥有一组来源于父scope的本地scope属性(local scope properties)的                     object hash。这些local properties对于为模版创建值的别名很有帮助(useful for aliasing values for templates!)。本地的定义是对其来源的一组本地scope property的hash映射(Locals                  definition is a hash of local scope property to its source))():

                       @或@attr - 建立一个local scope property到DOM属性的绑定。因为属性值总是String类型,所以这个值总是返回一个字符串。如果没有通过@attr指定属性名称,那么本地名称将与                                          DOM属性的名称一直。例如<widget my-attr='hello {{name}}'>,widget的scope定义为:{localName:’@myAttr’}。那么,widget scope property的localName会映射                                                 出”hello {{name}}"转换后的真实值。name属性值改变后,widget scope的localName属性也会相应地改变(仅仅单向,与下面的”=”不同)。name属性是在父scope读取                                         的(不是组件scope)

                        =或=expression(这里也许是attr) - 在本地scope属性与parent scope属性之间设置双向的绑定。如果没有指定attr名称,那么本地名称将与属性名称一致。例如<widget my-                                                   attr=”parentModel”>,widget定义的scope为:{localModel:’=myAttr’},那么widget scope property “localName”将会映射父scope的“parentModel”。如果parentModel发生                                       任何改变,localModel也会发生改变,反之亦然。(双向绑定)

                       &或&attr - 提供一个在父scope上下文中执行一个表达式的途径。如果没有指定attr的名称,那么local name将与属性名称一致。例如<widget my-attr=”count = count + value”>,                                             widget的scope定义为:{localFn:’increment()’},那么isolate scope property “localFn”会指向一个包裹着increment()表达式的function。一般来说,我们希望通过一个表达                                         式,将数据从isolate scope传到parent scope中。这可以通过传送一个本地变量键值的映射到表达式的wrapper函数中来完成。例如,如果表达式是increment(amount),那                                     么我们可以通过localFn({amount:22})的方式调用localFn以指定amount的值。

    controller - controller 构造函数。controller会在pre-linking步骤之前进行初始化,并允许其他directive通过指定名称的require进行共享(看下面的require属性)。这将允许directive之间相互沟通,增强相互之间的行为。controller默认注入了以下本地对象到link:

         

        $scope - 与当前元素结合的scope
        $element - 当前的元素
        $attrs - 当前元素的属性对象
        $transclude - 一个预先绑定到当前转置scope的转置linking function :function(cloneLinkingFn)。(A transclude;linking function pre-bound to the correct transclusion scope)

    require - 请求另外的controller,传入当前directive的linking function中。require需要传入一个directive controller的名称。如果找不到这个名称对应的controller,那么将会抛出一个error。名称可以                加入以下前缀:

                   

                                      ? - 不要抛出异常。这使这个依赖变为一个可选项。<br />
                                      ^ - 允许查找父元素的controller<br /><br />

    restrict - EACM的子集的字符串,它限制directive为指定的声明方式。如果省略的话,directive将仅仅允许通过属性声明:E - 元素名称 A - 属性名 C - class名 M - 注释

    template - 如果replace 为true,则将模版内容替换当前的HTML元素,并将原来元素的属性、class一并迁移;如果为false,则将模版元素当作当前元素的子元素处理。

    templateUrl - 与template基本一致,但模版通过指定的url进行加载。因为模版加载是异步的,所以compilation、linking都会暂停,等待加载完毕后再执行。

    replace - 如果设置为true,那么模版将会替换当前元素,而不是作为子元素添加到当前元素中。(注:为true时,模版必须有一个根节点)

    transclude - 编译元素的内容,使它能够被directive所用。需要(在模版中)配合ngTransclude使用(引用)。transclusion的优点是linking function能够得到一个预先与当前scope绑定的transclusion                        function。一般地,建立一个widget,创建isolate scope,transclusion不是子级的,而是isolate scope的兄弟。这将使得widget拥有私有的状态,transclusion会被绑定到父级                                (preisolate)scope中。

                       true - 转换这个directive的内容。

                      ‘element’ - 转换整个元素,包括其他优先级较低的directive。(像将整体内容编译后,当作一个整体(外面再包裹p),插入到指定地方)

    compile - compile function

    link - link function,这个属性仅仅是在compile属性没有定义的情况下使用。

    好了,以上内容就是鄙人的一些见解,望大家能够更好的了解angularjs directive的使用及原理。转载请注明出处!谢谢

    转载于:https://www.cnblogs.com/houMing/p/5132655.html

    展开全文
  • 如何分析及解决oom问题? 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇...
  • 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • Google一下关键字“需求分析”,网上已经有很多相关的文章了,有不少已经写得像教科书一样全面准确,还提供了一些最佳实践的分类方法。我这篇就从个人经验方面谈一点自己的体会好了。首先,最重要的一个问题就是,为...
  • 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • 写在前面,如果面对复杂的动画效果你一筹莫展,不烦看看这篇文章:LottieAndroid使用详解及源码解析—轻而易举实现...本文篇幅较长,几乎涵盖了所有的性能方面问题,以及给出了如何查找和解决问题的方案,几乎是史上...
  • 刚开始接触css样式百度最多的就是balabala如何居中,因为不懂原理,每次凑出来就忘记了,前段时间看到一个很全面分析刚好记下来了,现在基本光靠这份笔记就可以解决几乎所有的元素的居中问题,再也不用去百度了!...
  • 全面分析PostBack之Client Script -Written by 浪子@cnblogs.com (2006.08.14)[JavaScript]自定义MessageBox ,我还剩下一个问题没有解决,即"如何获取control的完整的客户端代码"?。所以本文解决的问题只涉及...
  • 写在前面智能门锁已经在普通家庭...接下来我们带着诸多疑惑一起来看看德施曼R8智能锁是如何解决这些问题。作为数码圈的积极分子,关注智能锁已经好多年,为什么近期才急着换掉传统锁呢?一是因为家人总有忘带钥匙,...
  • 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • 最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • 转载自:https://www.cnblogs.com/ThinkVenus/p/6805495.html最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说...
  • 点击上方石杉的架构笔记,右上角选择“设为星标”每日早8点半,技术文章准时送上公众号后台回复“学习”,获取作者独家秘制精品资料往期文章BAT 面试官是如何360°无死角考察...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,626
精华内容 650
关键字:

如何全面分析问题