jquery在项目中做复选框时遇到的一些问题笔记

关于复选框

最近在重新翻看继续学习《锋利的jQuery》这本书中对复选框最基本的应用(对复选框进行全选、全不选和反选),在全选和全不选中遇到了一个诡异的问题

项目中遇到的问题,项目遇到问题

一、Spring 事务问题

1.描述:service1 中的 a 调用 b,b 调用了 service2 中的 c ,c 调用了
service3 中的 d

期望:d 抛出异常时(我真实项目中抛出的是 Sql 异常),d,c 回滚,而 a,b
不回滚。

测试:考虑到 Spring 事务的自调用和 cglib 动态代理下的 spring
事务配置。添加了 <aop:aspectj-autoproxy expose-proxy=”true”
proxy-target-class=”true”/>。

Demo:

自定义异常:

图片 1public
class MyException extends SQLException { private static final long
serialVersionUID = 1L; public MyException() { super(); } public
MyException(String reason, String sqlState, int vendorCode, Throwable
cause) { super(reason, sqlState, vendorCode, cause); } public
MyException(String reason, String SQLState, int vendorCode) {
super(reason, SQLState, vendorCode); } public MyException(String reason,
String sqlState, Throwable cause) { super(reason, sqlState, cause); }
public MyException(String reason, String SQLState) { super(reason,
SQLState); } public MyException(String reason, Throwable cause) {
super(reason, cause); } public MyException(String reason) {
super(reason); } public MyException(Throwable cause) { super(cause); } }
MyException.java

Dao:

图片 2@Repository
public class TxDao { @Autowired private JdbcTemplate jdbcTemplate;
public void updateA() { String sql = “update tx_test set a_field = 1
where id = 1”; jdbcTemplate.update(sql); } public void updateB() {
String sql = “update tx_test set b_field = 1 where id = 1”;
jdbcTemplate.update(sql); } public void updateC() { String sql = “update
tx_test set c_field = 1 where id = 1”; jdbcTemplate.update(sql); }
public void updateD() { String sql = “update tx_test set d_field = 1
where id = 1”; jdbcTemplate.update(sql); } } TxDao.java

ABService:

图片 3@Service
public class ABService { @Autowired private TxDao txDao; @Autowired
private CService cService; @Transactional public void aMethod() throws
MyException { System.out.println(“aMethod”); txDao.updateA();
((ABService) AopContext.currentProxy()).bMetod(); } @Transactional
public void bMetod() throws MyException { System.out.println(“bMethod”);
txDao.updateB(); cService.cMethod(); } } ABService.java

CService:

图片 4@Service
public class CService { @Autowired private TxDao txDao; @Autowired
private DService dService; @Transactional(rollbackFor=MyException.class)
public void cMethod() throws MyException {
System.out.println(“cMethod…”); txDao.updateC(); dService.dMethod(); }
} CService.java

DService:

图片 5@Service
public class DService { @Autowired private TxDao txDao;
@Transactional(rollbackFor=MyException.class) public void dMethod()
throws MyException{ System.out.println(“dMethod…”); txDao.updateD();
throw new MyException(); } } DService.java

测试代码:

图片 6@Test
public void test() { ABService service =
context.getBean(ABService.class); try { service.aMethod(); }
catch(MyException e) { e.printStackTrace(); } } View Code

(1)测试 rollbackFor 和 noRollbackFor

过程:

自定义了一个 Sql 异常 MyException 继承自 SQLException,从 d
抛出,一直向上抛。

对 a, b 的 @Transactional 的 noRollbackFor 属性设置为
MyException.class,而 c,d 的 rollbackFor 属性设置为 MyException.class。

控制台输出:

aMethod
bMethod
cMethod…
dMethod…

数据库输出:

图片 7

测试结果: a,b,c,d 四个方法全部回滚。

原因查找:发现在容器初始化的时候就读取了所有的 事务方法的 RollBackFor
和  noRollBackFor 属性定义的 Value 值。

详细参见:org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(java.lang.Class<?>)

在某个事务方法抛出异常后,整个事务都进行了回滚,感觉与配置 noRollBackFor
没有关系。

详细参见:org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
            throws Throwable {

// If the transaction attribute is null, the method is non-transactional.
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass);

if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
    // Standard transaction demarcation with getTransaction and commit/rollback calls.
    TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
    Object retVal = null;
    try {
        // This is an around advice: Invoke the next interceptor in the chain.
        // This will normally result in a target object being invoked.
        retVal = invocation.proceedWithInvocation();
    }
    catch (Throwable ex) {
        // target invocation exception
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
    }
    finally {
        cleanupTransactionInfo(txInfo);
    }
    commitTransactionAfterReturning(txInfo);
    return retVal;
}

在标红的地方会去掉目标方法,如目标方法抛出异常,则会进入到 catch
块,执行完 catch 块的代码继续向上抛出。catch 块能捕获到 MyException。

通过断点跟踪发现在 completeTransactionAfterThrowing()
方法里进行了回滚,等回滚之后最后去调用了
commitTransactionAfterReturning() 方法。

这样看来 noRollBackFor
甚至没有什么作用,有哪位大神看到这里并且知道原理的话,请不吝赐教,谢谢。

(2)测试 Spring 事务的传播行为。

过程:将 c 的传播行为改为 REQUIRES_NEW,其他还是默认。同时在 c
方法中处理了 d 抛上来的异常。

控制台输出:

aMethod
bMethod
cMethod…

数据库输出:

图片 8

发现根本就不会去执行 d 方法。这里就不是很明白了。

上面提供了两个测试,事实上测试了  n 种方式,都没有行的通。等以后对
spring 事务理解加深之后再来解析。这里直接说最终的解决办法。

解决办法:

1.手动控制事务

2.服务拆分,比如这里 a,b 单独事务,c,d 单独事务。

 

一、Spring
事务问题 1.描述:service1 中的 a 调用 b,b 调用了 service2 中的 c ,c
调用了 service3 中的 d 期望:…

//复选框全部选定或者全部不选定

昨天在做一个复选框的时候,一开始以为应该挺简单的,想当然了一下,主要的功能就是点击一个按钮,比如是全部选中这个一个功能,然后下面的所有列表全部选中的效果。

html代码:

function selectAll(){

后来在实践中还是遇到了很多的问题,注意在input的checkbox中,用普通的attr属性来判断是不可以的,因为checked的值是checked,只有用prop这个属性才能该改变!!!!见api文档,后来在百度中发现了这个在官方的api中就已经有说明了,附上jquery中一个prop的api地址

                <div>
                    你的爱好运动是?
                    <input type=”checkbox” name=”items”
value=”足球” />足球
                    <input type=”checkbox” name=”items”
value=”篮球” />篮球
                    <input type=”checkbox” name=”items”
value=”羽毛球” />羽毛球
                    <input type=”checkbox” name=”items”
value=”乒乓球” />乒乓球
                </div>
                <div>
                    <input type=”button” id=”checkAll” name=”name”
value=”全选” />
                    <input type=”button” id=”checkNo” name=”name”
value=”全不选” />
                    <input type=”button” id=”checkedRev”
name=”name” value=”反选” />
                    <input type=”button” id=”summit” name=”name”
value=”提交” />
                </div>

$(“#deleteAll”).change(function(){
if($(this).attr(“checked”)==”checked”){
$(“input[name=’deleteCheck’]”).each(function(){
$(this).attr(“checked”,true);
});
}else{
$(“input[name=’deleteCheck’]”).each(function(){
$(this).attr(“checked”,false);
});
}
});
}

复制代码 代码如下:

 

function
selectAll(){ $(#deleteAll).change(function(){
if($(this).attr(checked)==checked){
$(input[name=deleteCheck]).each(function(){…

$(“#main-manage”).on(‘click’,”#selectAll”, function(event) {
$(“#xunTable”).find(‘input’).not(“:disabled”).each(function(index, el)
{
if($(“#selectAll”).is(“:checked”)){
$(this).prop(‘checked’, ‘true’);
}
else{
$(this).prop(‘checked’, ‘false’);
$(this).removeAttr(‘checked’);
}
});
});

jQuery代码:

昨天在做一个复选框的时候,一开始以为应该挺简单的,想当然了一下,主要的功能就是点击一个按钮,比如是全部选中这个一…

$(“#checkAll”).click(function() {     //全选
        $(“[name=items]:checkbox”).attr(‘checked’, true);
    });
    $(“#checkNo”).click(function() {  //全不选
        $(“[name=items]:checkbox”).attr(‘checked’, false);
    })
    $(“#checkedRev”).click(function() {  //反选
        $(“[name=items]:checkbox”).attr(function() {
            this.checked = !this.checked;
        });
    });

然而这样写会出现一个奇怪又诡异的问题:第一次执行全选然后执行全不选或者先执行全不选然后全选时,程序是运行正常的,然后当点击第二次全选或者全不选时,选项前面的勾就没有再勾上了。

 

这时我们就不得不谈谈jQuery中attr()和prop()方法的异同了:

在jQuery1.6版之前,都是使用attr()方法来访问对象属性的,例如取一个图片的alt属性,就可以使用$(“img”).attr(“alt”)

但是在访问input的disabled属性的时候,就会有些问题。在有些浏览器里,只要写了disabled属性就可以,有些则要写:disabled=“disabled”。

而在使用prop时。返回值是标准属性:true/false,例如$(“#check”).prop(“checked”)不会返回“disabled”或“”只会返回true/false。

当然,赋值的时候也如此。

 

那什么情况下使用attr()什么时候使用attr呢:

第一个原则:只添加属性名称该属性就会生效应该使用prop()

第二个原则:只存在true/false的属性应该使用prop()

因此,代码更正如下:

$(“#checkAll”).click(function() {     //全选
        $(“[name=items]:checkbox”).prop(‘checked’, true);
    });
    $(“#checkNo”).click(function() {  //全不选
        $(“[name=items]:checkbox”).prop(‘checked’, false);
    })
    $(“#checkedRev”).click(function() {  //反选
        $(“[name=items]:checkbox”).prop(function() {
            this.checked = !this.checked;
        });
    });

发表评论

电子邮件地址不会被公开。 必填项已用*标注